Skip to content

Commit

Permalink
Add command deduplication docs (#4693)
Browse files Browse the repository at this point in the history
CHANGELOG_BEGIN
CHANGELOG_END
  • Loading branch information
rautenrieth-da authored Mar 9, 2020
1 parent e67fef1 commit 6f8c3ad
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
24 changes: 24 additions & 0 deletions docs/source/app-dev/app-arch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,27 @@ typical DAML developer workflow is to
#. Make further changes either to your DAML and/or React code until you're happy with what you've developed

.. image:: ./developer_workflow.svg

.. _handling-submission-failures:

Handle failures when submitting commands
****************************************

The interaction of a DAML application with the ledger is inherently asynchronous: applications send commands to the ledger, and some time later they see the effect of that command on the ledger.

There are several things that can fail during this time window: the application can crash, the participant node can crash, messages can be lost on the network, or the ledger may be just slow to respond due to a high load.

If you want to make sure that a command is not executed twice, your application needs to robustly handle all the various failure scenarios.
DAML ledgers provide a mechanism for :ref:`command deduplication <command-submission-service-deduplication>` to help deal this problem.

For each command applications provide a command ID and an optional parameter that specifies the deduplication time. If the latter parameter is not specified in the command submission itself, the ledger will fall back to using the configured maximum deduplication time.
The ledger will then guarantee that commands for the same submitting party and command ID will be ignored within the deduplication time window.

To use command deduplication, you should:

- Use generous values for the deduplication time. It should be large enough such that you can assume the command was permanently lost if the deduplication time has passed and you still don’t observe any effect of the command on the ledger (i.e. you don't see a transaction with the command ID via the :ref:`transaction service <transaction-service>`).
- Make sure you set command IDs deterministically, that is to say: the "same" command must use the same command ID. This is useful for the recovery procedure after an application crash/restart, in which the application inspects the state of the ledger (e.g. via the :ref:`Active contracts service <active-contract-service>`) and sends commands to the ledger. When using deterministic command IDs, any commands that had been sent before the application restart will be discarded by the ledger to avoid duplicate submissions.
- If you are not sure whether a command was submitted successfully, just resubmit it. If the new command was submitted within the deduplication time window, the duplicate submission will safely be ignored. If the deduplication time window has passed, you can assume the command was lost or rejected and a new submission is justified.


For more details on command deduplication, see the :ref:`Ledger API Services <command-submission-service-deduplication>` documentation.
20 changes: 20 additions & 0 deletions docs/source/app-dev/services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ Commands can be labeled with two application-specific IDs, both of which are ret

For full details, see :ref:`the proto documentation for the service <com.digitalasset.ledger.api.v1.CommandSubmissionService>`.

.. _command-submission-service-deduplication:

Command deduplication
---------------------

The command submission service deduplicates submitted commands based on the submitting :ref:`party <com.digitalasset.ledger.api.v1.Commands.party>` and :ref:`command ID <com.digitalasset.ledger.api.v1.Commands.command_id>`:

- Applications can provide a :ref:`deduplication time <com.digitalasset.ledger.api.v1.Commands.deduplication_time>` for each command. If this parameter is not set, the default maximum deduplication time is used.
- A command submission is considered a duplicate submission if the ledger server receives the command within the deduplication time of a previous command with the same command ID from the same submitting party.
- Duplicate command submissions will be ignored until either the deduplication time of the original command has elapsed or the original submission was rejected (i.e. the command failed and resulted in a rejected transaction), whichever comes first.
- Command deduplication is only *guaranteed* to work if all commands are submitted to the same participant. Ledgers are free to perform additional command deduplication across participants. Consult the respective ledger's manual for more details.
- A command submission will return:

- The result of the submission (``Empty`` or a gRPC error), if the command was submitted outside of the deduplication time of a previous command with the same command ID on the same participant.
- The status error ``ALREADY_EXISTS``, if the command was discarded by the ledger server because it was sent within the deduplication time of a previous command with the same command ID.

- If the ledger provides additional command deduplication across participants, the initial command submission might be successful, but ultimately the command can be rejected if the deduplication check fails on the ledger.

For details on how to use command deduplication, see the :ref:`Application Architecture Guide <handling-submission-failures>`.

.. _command-completion-service:

Command completion service
Expand Down

0 comments on commit 6f8c3ad

Please sign in to comment.