/// <summary> /// Calls the provided requests completion handler and waits for it to complete. /// </summary> /// <param name="request">The reqest.</param> /// <returns>A <see cref="Task"/> representing the work performed.</returns> private async Task CompleteOrderedReplication(ReplicationRequest request) { if (this.closing) { this.logger.Log(nameof(OperationReplicator <TOperation>) + nameof(this.CompleteOrderedReplication)); } try { var logSequenceNumber = await request.ReplicationCompleted.Task.ConfigureAwait(false); // Create a record to append. var version = new RecordVersion(this.stateProvider.CurrentEpoch, logSequenceNumber); var record = new OperationCommittedRecord <TOperation>(request.Operation, version); // Write the record. await this.stateProvider.AppendOperation(this.serializer.Serialize <Record>(record), logSequenceNumber).ConfigureAwait(false); } catch (Exception exception) { // If the error was caused by the state provider, propagate that exception. if (request.ReplicationCompleted.Task.Status == TaskStatus.RanToCompletion) { await request.CompletionHandler(Task.FromException <long>(exception)).ConfigureAwait(false); return; } } // Wait for the caller's completion handler to complete before continuing to // process other replication completion handlers. await request.CompletionHandler(request.ReplicationCompleted.Task).Suppressed().ConfigureAwait(false); }
/// <summary> /// Applies the provided, replicated <paramref name="operation"/>. /// </summary> /// <param name="operation">The operation.</param> /// <param name="cancellationtoken">The cancellation token.</param> /// <returns>A <see cref="Task"/> representing the work performed.</returns> public async Task ApplyReplicationOperation(IOperation operation, CancellationToken cancellationtoken) { try { foreach (var operationData in operation.Data) { var op = this.serializer.Deserialize <TOperation>(operationData); // Create a record to append. var version = new RecordVersion(this.stateProvider.CurrentEpoch, operation.SequenceNumber); var record = new OperationCommittedRecord <TOperation>(op, version); // Append the operation to the log at the current epoch. await this.stateProvider.AppendOperation(this.serializer.Serialize <Record>(record), operation.SequenceNumber); } } catch (Exception exception) { this.logger.Log($"Exception in {nameof(this.ApplyReplicationOperation)}: {exception}"); this.partition.ReportFault(FaultType.Transient); throw; } }