IStateReplicator.ReplicateAsync(OperationData, CancellationToken, Int64) Method


Replicates state changes from Primary replica to the Secondary replicas and receives a quorum acknowledgement that those state changes have been applied.

public System.Threading.Tasks.Task<long> ReplicateAsync (System.Fabric.OperationData operationData, System.Threading.CancellationToken cancellationToken, out long sequenceNumber);
abstract member ReplicateAsync : System.Fabric.OperationData * System.Threading.CancellationToken *  -> System.Threading.Tasks.Task<int64>



The OperationData that represents the state change that the Primary replica wants to replicate.


A write quorum of replicas that have been lost. It can be used to send a notification that the operation should be canceled. Note that cancellation is advisory and that the operation might still be completed even if it is canceled.


Long, the LSN of the operation. Note that this is the same value which is returned by the task. Providing it as an out parameter is useful for services which want to prepare the local write to commit when the task finishes.



Returns System.Threading.Tasks.Task`1 of type long, the LSN of the operation.



Caused by one of the following:

E_INVALIDARG is returned when one or more arguments are not valid.

FabricTransientException is a retriable exception. It is caused by one of the following;

NoWriteQuorum is returned when the replicator does not currently have write quorum..

ReconfigurationPending is returned when the replicator has a pending reconfiguration.

ReplicationQueueFull is returned when the replicator queue is full.

FabricNotPrimaryException is caused by one of the following;

NotPrimary is returned when the replicator has a pending reconfiguration.

FabricObjectClosedException is caused by one of the following;

ObjectClosed is returned when the replicator has been closed.


System.OperationCanceledException is caused by one of the following;

E_ABORT when replicator cancels an inflight replication operation.


Replication at the Primary replica produces the objects that implement IOperation that the Secondary replica obtains from the Replication Stream via GetReplicationStream(), which is followed by GetOperationAsync(CancellationToken).

The Primary replica has many duties that are related to process state updates. The following steps show the general sequence of events that a Primary replica must handle to replicate and acknowledge a change.

Part 1: Handling incoming requests: Receive request: Write(x) – Service receives a write request, x. CheckArguments – The service checks the arguments of the request. This check helps ensure the consistency of the service’s state.

Check current state – The service examines its current state to ensure that the operation is valid and can or should be performed. This check also helps ensure data consistency. It is performed by the service code.

Acquire Locks – The service should acquire the necessary locks to prevent additional operations from occurring at the same time. This operation helps ensure isolation and consistency.

Attempt Operation (optional) – The service can attempt the operation locally. This step reserves and allocates space and performs all the necessary computations. This step includes everything but the actual commit of the result. This operation improves the durability of the operation and makes later failures very unlikely.

Manufacture the OperationData – An OperationData object is the representation of the Write(x) that was presented to the service. The OperationData object contains the state change to be transferred with acknowledgement from the Primary replica to the Secondary replicas. The data that the service places in the OperationData defines the atomic update that the FabricReplicator transfers to the Secondary replicas. Note that creating of the OperationData object requires one or more byte arrays. The service must itself determine and serialize the change in state, and then provide this set of bytes to the FabricReplicator via ReplicateAsync(OperationData, CancellationToken, Int64). The service sends the operation to the FabricReplicator and receives a logical sequence number (LSN) in return. The LSN is the identity for the operation and helps both the service and Service Fabric ensure that operations are always applied in the same order everywhere.The service should record the OperationData along with its LSN in an ordered list of in-flight operations. This ensures that when the operations are completed, they can be consistently applied in the correct order.

Release Locks - Continue processing or waiting for further requests.

Part 2: Completing requests and responding: The Primary replica receives a callback that indicates that the operation has been applied. ReplicateAsync is completed. This callback indicates that the operation has been acknowledged by a quorum of the replicas in the replica set. When the Primary replica receives this callback, it should perform the following actions:

Find the corresponding operation that is indicated by the long LSN that is returned from ReplicateAsync in the service’s in-flight list and mark it as "QuorumAck’d".

Now, starting at the first operation in the in-flight list, go through the list and locally commit all of the QuorumAck’d operations, finish any changes to the local state and mark the state changes with their corresponding LSN, until the first incomplete operation is encountered. This ensures that ordering is preserved (consistency) and that the operations are actually applied. This takes advantage of the previous durability and isolation preparations. Note: Most services should cache the last committed LSN value so that responses to the GetLastCommittedSequenceNumber() do not require querying the actual store for the greatest LSN.

When an operation is successfully committed at the Primary replica, the Primary replica can now reply to the client that initiated the call and remove the operation from the in-flight list. Continue to wait for the next quorum-acknowledgment callback.

Applies to