Java Bindings: ledgerClient.activeContractSetClient.getActiveContracts returns flowable but is it actually a stream?

Hi

does the activeContracts client return a stream?

The examples show a samples such as:

        val transactions: Flowable<Transaction> = ledger.transactionsClient.getTransactions(
            LedgerOffset.LedgerEnd.getInstance(),
            FiltersByParty(mapOf(Pair("myPartyIdGoesHere", NoFilter.instance))), true
        )
        transactions.forEach{
            log.info("received a transaction")
        }

which works.

But if you replicate for the ACS client, the OnCompletion event is received after the first query.

EDIT: TLDR: The ACS API returns a bounded stream based on the current ACS. after the current ACS is returned in the steam, the stream closes and you are to use the Transactions API to get further updates (as per the docs).

The stream for the ACS API returns “lists of contracts” per message in the stream, but it is not clear what is the max size of the list in a single message.

Yes, it’s a stream, and each item of the stream can include several active contracts (see the documentation here). If the active contract set is small enough it will fit in a single response before completing.

1 Like

What is the size of each item in the stream?

So it is a bound stream based on a fixed query? Vs the transaction api providing a unbounded stream based on the activity occurring in the ledger.

Not sure.

Yes, the active contracts service returns you the latest set of active contracts available at the moment of querying and the offset at which that is valid. You can start asking for the “transactions” or “flat transactions” (as opposed to “transaction trees”) to keep that view up to date locally as more contracts get created and archived. You can read more about it here.

This is undefined by the API. It’s “some, or all, of them”.

This is also undefined, though it is very commonly true.

Clients SHOULD NOT assume that the set of active contracts they receive reflects the state at the ledger end.

The pattern @stefanobaghino-da suggests is the correct pattern; for example, the JSON API (which is just a proxy to the ledger API)

  1. checks the ledger end
  2. queries the ACS
  3. if the ACS end offset < the ledger end from (1), uses bounded transaction stream to “catch up”

Speaking of which

It is either unbounded or bounded, depending on what you put in your request.

Thanks. What was throwing me off was that it was a bounded stream and that it would emit multiple packages of the acs (rather than just a stream of contracts it is a stream of List).

Understanding the max number of contracts returned in a single event would be helpful. (would be great if we could control this as well so backpressure can be managed

It is either unbounded or bounded, depending on what you put in your request.

@Stephen how so? It seems like it is bounded regardless: As it would still return a completion event of the stream when it reaches the end of the ACS. (at least how it is behaving in the java bindings)

Edit:

This is undefined by the API. It’s “some, or all, of them”.

is there further info on this? or a spot in the code we can look at for the current internal configs? Am i going to get 100, 1000, 100,000,000 contracts in a single event? or would it be broken in multiple events. such as 1000 contracts per event in the stream?

You were referring to the transaction stream in the prior quote, and so I alluded to end.

I would recommend making this a separate topic.

You were referring to the transaction stream in the prior quote, and

sorry yes you are correct.

Continued max number of contracts returned per list in: Active Contract Set Service returns a Stream Arrays/List: how big can the arrays/List be per event in the stream?