コード例 #1
0
        /// <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);
        }
コード例 #2
0
        public override Task <Empty> Replicate(ReplicationRequest request, ServerCallContext context)
        {
            if (request.Offset >= _storage.LatestOffset)
            {
                _storage.Add(request.Offset, request.Message.ToByteArray());
            }

            return(Task.FromResult(new Empty()));
        }
コード例 #3
0
        /// <summary>
        /// Starts replication of the provided <paramref name="request"/>, ensuring that its completion handler will
        /// be invoked in the order of replication.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>A <see cref="Task"/> representing the work performed.</returns>
        private Task InitiateOrderedReplication(ReplicationRequest request)
        {
            if (this.closing)
            {
                this.logger.Log(nameof(OperationReplicator <TOperation>) + nameof(this.InitiateOrderedReplication));
            }
            try
            {
                // If the request has already been cancelled, return without initiating replication.
                if (request.Cancellation.IsCancellationRequested)
                {
                    request.Cancel();
                    return(Task.FromResult(0));
                }

                // To ensure that replication completion handlers are invoked in the order they were
                // replicated in, post them to the completion worker from this replication worker.
                this.completionWorker.Post(request);

                // Start replicating the operation. Do not wait for replication to complete, but instead
                // propagate the result to the completion task so that the completion worker can handle
                // it in its due turn.
                long sequenceNumber;
                this.replicator.ReplicateAsync(request.OperationData, request.Cancellation, out sequenceNumber)
                .PropagateToCompletion(request.ReplicationCompleted);
                if (this.closing)
                {
                    this.logger.Log("Completed " + nameof(OperationReplicator <TOperation>) + nameof(this.InitiateOrderedReplication));
                }
                return(Task.FromResult(0));
            }
            catch (Exception exception)
            {
                // Replication failed, notify the requester.
                request.ReplicationCompleted.TrySetException(exception);
                throw;
            }
        }