Do Daml Hub integrations allow for atomic ledger update composition?

A more verbose formulation of the question: do Daml Hub integrations allow for composing a) the ledger update initiating the API call, and b) the ledger update receiving the answer from the API in an atomic manner?

Like the business transactions marked with dotted rectangles in the diagram below, where the business transactions are supposed to be atomic:

If I’m understanding the question properly, the answer is unfortunately no: there is no way, on any Daml ledger, Hub or otherwise, for an external action to happen within a Daml transaction.

The ledger update (which came from a different transaction) causes the integration to make an external request. That external request could come back within a few milliseconds, could come back in an hour, or could never come back—there’s simply no way of knowing.

Consider the scenario where the external API is down: the ledger update and the external API request somehow exist, but not as a transaction because transactions cannot be modified after they have been “committed” to a ledger. They’d have to somehow exist in a different, mutable way that would “change” to a finalized request/response pair. Or if you kept them requests the transaction stream entirely until responses were done, you couldn’t look at the ledger to know that an outstanding request is in flight.

You can use a workflow ID (see The Ledger API Services — Daml SDK 2.3.2 documentation) to correlate transactions that are related for a business purpose, but there isn’t any guarantee of transactionality across individual transactions with the same workflow ID (and it’s not clear to me that you’d really want that guarantee in practice because of the error scenarios I mentioned).

Hope this helps!

3 Likes

Yes, thank you!

I’ve marked you answer as a solution already, but now I’m not sure I completely understand it. Or I didn’t formulate my question properly.

I’m thinking about the ledger updates (which may or may not call the external API) to be able to be composed in a monadic way. Like two Daml updates or Haskell IO actions.

This is also true for a Haskell IO action, still two IO actions can be composed monadically: “That external request could come back within a few milliseconds, could come back in an hour, or could never come back—there’s simply no way of knowing.”

Actually, I now realize that this would be a better diagram for what I’m thinking about:

I think the key thing is that a Daml transaction is always a “Ledger update” (to borrow the terminology from the picture), whereas a “business transaction” as you’ve defined it has no ledger atomicity guarantees, and it can’t because technical processes need to be able to see partial business transactions in order to continue to move the process along. There’s no sensible way to retroactively remove a business transaction as you’ve defined it because that would entail removing previous ledger transactions.

1 Like

Ok, thank you