private void FillHole(CommitAttempt attempt, Int64 checkpointId) { try { var holeFillDoc = attempt.ToEmptyCommit( checkpointId, _systemBucketName ); PersistedCommits.InsertOne(holeFillDoc); } catch (OutOfMemoryException) { throw; } catch (Exception e) { Logger.LogWarning(e, Messages.FillHoleError, attempt.CommitId, checkpointId, attempt.BucketId, attempt.StreamId, e); } }
public virtual ICommit Commit(CommitAttempt attempt) { if (Logger.IsDebugEnabled) { Logger.Debug(Messages.AttemptingToCommit, attempt.Events.Count, attempt.StreamId, attempt.CommitSequence); } return(TryMongo(() => { Int64 checkpointId; var commitDoc = attempt.ToMongoCommit( checkpointId = _checkpointGenerator.Next(), _serializer ); bool retry = true; while (retry) { try { // for concurrency / duplicate commit detection safe mode is required PersistedCommits.InsertOne(commitDoc); retry = false; if (!_options.DisableSnapshotSupport) { UpdateStreamHeadInBackgroundThread(attempt.BucketId, attempt.StreamId, attempt.StreamRevision, attempt.Events.Count); } if (Logger.IsDebugEnabled) { Logger.Debug(Messages.CommitPersisted, attempt.CommitId); } } catch (MongoException e) { if (!e.Message.Contains(ConcurrencyException)) { if (Logger.IsErrorEnabled) { Logger.Error(Messages.GenericPersistingError, attempt.CommitId, checkpointId, attempt.BucketId, attempt.StreamId, e); } throw; } // checkpoint index? if (e.Message.Contains(MongoCommitIndexes.CheckpointNumberMMApV1) || e.Message.Contains(MongoCommitIndexes.CheckpointNumberWiredTiger)) { if (Logger.IsWarnEnabled) { Logger.Warn(Messages.DuplicatedCheckpointTokenError, attempt.CommitId, checkpointId, attempt.BucketId, attempt.StreamId); } _checkpointGenerator.SignalDuplicateId(checkpointId); commitDoc[MongoCommitFields.CheckpointNumber] = checkpointId = _checkpointGenerator.Next(); } else { if (_options.ConcurrencyStrategy == ConcurrencyExceptionStrategy.FillHole) { FillHole(attempt, checkpointId); } if (e.Message.Contains(MongoCommitIndexes.CommitId)) { var msg = String.Format(Messages.DuplicatedCommitError, attempt.CommitId, checkpointId, attempt.BucketId, attempt.StreamId); if (Logger.IsInfoEnabled) { Logger.Info(msg); } throw new DuplicateCommitException(msg); } ICommit savedCommit = PersistedCommits .FindSync(attempt.ToMongoCommitIdQuery()) .FirstOrDefault() .ToCommit(_serializer); if (savedCommit != null && savedCommit.CommitId == attempt.CommitId) { var msg = String.Format(Messages.DuplicatedCommitError, attempt.CommitId, checkpointId, attempt.BucketId, attempt.StreamId); if (Logger.IsInfoEnabled) { Logger.Info(msg); } throw new DuplicateCommitException(msg); } if (Logger.IsInfoEnabled) { Logger.Info(Messages.ConcurrencyExceptionError, attempt.CommitId, checkpointId, attempt.BucketId, attempt.StreamId, e); } throw new ConcurrencyException(); } } } return commitDoc.ToCommit(_serializer); })); }