private void Received(OrderedCommitNotification msg) { //if their previous matches our current, project //if their previous is less than our current, ignore //if their previous is > our current, catchup var comparer = new CheckpointComparer(); var comparision = comparer.Compare(Checkpoint, msg.PreviousCheckpoint); if (comparision == 0) { Project(msg.Commit); //order matched, project } else if (comparision > 0) { //we are ahead of this commit so no-op, this is a bit odd, so log it Context.GetLogger().Debug("Received a commit notification (checkpoint {0}) behind our checkpoint ({1})", msg.Commit.CheckpointToken, Checkpoint.Get()); } else { //we are behind the head, should catch up var fromPoint = Checkpoint.Map(x => x.ToString()).GetOrElse("beginning of time"); Context.GetLogger().Info("Catchup started from checkpoint {0} after receiving out-of-sequence commit with checkpoint {1} and previous checkpoint {2}", fromPoint, msg.Commit.CheckpointToken, msg.PreviousCheckpoint); Catchup(); Context.GetLogger().Info("Catchup finished from {0} to checkpoint {1} after receiving commit with checkpoint {2}", fromPoint, Checkpoint.Map(x => x.ToString()).GetOrElse("beginning of time"), msg.Commit.CheckpointToken); } }
/// <summary> /// Catches-up the projector if it has fallen behind the head /// </summary> protected virtual void Catchup() { var comparer = new CheckpointComparer(); IEnumerable <ICommit> commits = _persistStreams.GetFrom(Checkpoint.GetOrElse(() => 0)); //load all commits after our current checkpoint from db foreach (var commit in commits) { Project(commit); if (comparer.Compare(Checkpoint, commit.CheckpointToken.ToSome()) != 0) { //something went wrong, we couldn't project Context.GetLogger().Warning("Stopped catchup! was unable to project the commit at checkpoint {0}", commit.CheckpointToken); break; } } }