/// <summary> /// Replay all events since the last snapshot. /// </summary> /// <returns> /// A <see cref="Task"/> representing the work performed. /// </returns> public async Task ReplayUnappliedEvents() { if (!this.IsBeingReplayed) { try { this.IsBeingReplayed = true; var currentEventId = this.LastJournaledEventId; await this.journal.ReadFrom(currentEventId).ForEachAsync( async @event => { // Update internal state. if (@event.EventId > this.LastJournaledEventId) { this.LastJournaledEventId = @event.EventId; } // Deserialize the event. var request = SerializationManager.DeserializeFromByteArray <MethodInvocation>(@event.Event); // Apply the event. await GrainExecutionHelper.ApplyRequest(this.grain, request); }); } finally { this.IsBeingReplayed = false; } } }
/// <summary> /// Journal the current request. /// </summary> /// <returns> /// The <see cref="Task"/>. /// </returns> public async Task WriteJournal() { if (!this.IsBeingReplayed) { if (++this.journaledSinceLastSnapshot % this.journalWritesBetweenSnapshots == 0) { await this.WriteSnapshot(); } var currentRequest = GrainExecutionHelper.CurrentRequest(this.grain); if (currentRequest != null) { var bytes = SerializationManager.SerializeToByteArray(currentRequest); var nextEventId = this.LastJournaledEventId + 1; await this.journal.Append(bytes, nextEventId); this.LastJournaledEventId = nextEventId; } } }