/// <summary> /// Stops replicating outgoing operations. /// </summary> /// <param name="cancellationToken"> /// The cancellation token. /// </param> /// <remarks> /// This should be called on transition out of the <see cref="ReplicaRole.Primary"/> role. /// </remarks> /// <returns>A <see cref="Task"/> representing the work performed.</returns> private async Task StopReplicatingOutgoingOperations(CancellationToken cancellationToken) { this.logger.Log(nameof(this.StopReplicatingOutgoingOperations)); var serviceListener = Interlocked.Exchange(ref this.listener, null); if (serviceListener != null) { await serviceListener.CloseAsync(cancellationToken); } if (this.service != null) { await this.service.Close(cancellationToken); } this.reliableJournal = null; var pusher = Interlocked.Exchange(ref this.operationReplicator, null); if (pusher != null) { await pusher.Close(); } this.logger.Log("Completed " + nameof(this.StopReplicatingOutgoingOperations)); }
/// <summary> /// Starts replicating outgoing operations. /// </summary> /// <param name="cancellationToken"> /// The cancellation token. /// </param> /// <remarks> /// This should be called on transition into the <see cref="ReplicaRole.Primary"/> role. /// </remarks> private async Task <string> StartReplicatingOutgoingOperations(CancellationToken cancellationToken) { this.logger.Log(nameof(this.StartReplicatingOutgoingOperations)); this.operationReplicator = new OperationReplicator <TOperation>( this.fabricReplicator.StateReplicator2, this.stateProvider, this.logger, this.serializer); // Open the service. this.reliableJournal = new ReliableJournal <TOperation>(this.operationReplicator, this.service); this.listener = this.service.CreateCommunicationListener(this.serviceParameters); await this.service.Open(this.reliableJournal, cancellationToken); // Apply existing events foreach (var entry in this.stateProvider.GetOperations()) { var operationRecord = this.serializer.Deserialize <Record>(entry.Data) as OperationCommittedRecord <TOperation>; if (operationRecord == null) { continue; } var eventOperation = operationRecord.Operation; if (eventOperation != null) { //this.logger.Log($"Applying stored event {eventOperation.Event}"); await this.service.Apply(eventOperation, cancellationToken); } } this.logger.Log("Completed " + nameof(this.StartReplicatingOutgoingOperations)); return(await this.listener.OpenAsync(cancellationToken)); }
/// <summary> /// Opens the service to handle requests. /// </summary> /// <param name="journal">The journal.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The address of this service, which clients can find using service discovery. /// </returns> public Task Open(IReliableJournal <Operation> journal, CancellationToken cancellationToken) { this.journal = journal; Debug.WriteLine($"[{nameof(KeyValueStore)}] Open"); return(Task.FromResult(string.Empty)); }
/// <summary> /// Closes this service. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="Task"/> representing the work performed.</returns> /// <remarks>The service may be re-opened at a later time.</remarks> public Task Close(CancellationToken cancellationToken) { Debug.WriteLine($"[{nameof(KeyValueStore)}] Close"); this.journal = null; return(Task.FromResult(0)); }