protected override void Context()
            {
                _alreadyCommitted  = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                _beyondEndOfStream = BuildCommitAttemptStub(HeadStreamRevision + 1, BeyondEndOfStreamCommitSequence);

                Hook.PostCommit(_alreadyCommitted);
            }
        public virtual async Task <ICommit> CommitAsync(CommitAttempt attempt, CancellationToken cancellationToken)
        {
            Guard.NotNull(() => attempt, attempt);

            foreach (var hook in _pipelineHooks)
            {
                cancellationToken.ThrowIfCancellationRequested();

                Logger.Debug(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType());
                if (await hook.PreCommitAsync(attempt, cancellationToken).ConfigureAwait(false))
                {
                    continue;
                }

                Logger.Info(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId);
                return(null);
            }

            // Last chance before we attempt to commit
            cancellationToken.ThrowIfCancellationRequested();

            Logger.Info(Resources.CommittingAttempt, attempt.CommitId, attempt.Events.Count);
            var commit = await _persistence.CommitAsync(attempt, cancellationToken).ConfigureAwait(false);

            foreach (var hook in _pipelineHooks)
            {
                Logger.Debug(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType());
                await hook.PostCommitAsync(commit, cancellationToken).ConfigureAwait(false);
            }

            return(commit);
        }
        public virtual ICommit Commit(CommitAttempt attempt)
        {
            Guard.NotNull(() => attempt, attempt);
            foreach (var hook in _pipelineHooks)
            {
                Logger.Debug(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType());
                if (hook.PreCommit(attempt))
                {
                    continue;
                }

                Logger.Info(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId);
                return null;
            }

            Logger.Info(Resources.CommittingAttempt, attempt.CommitId, attempt.Events.Count);
            ICommit commit = _persistence.Commit(attempt);

            foreach (var hook in _pipelineHooks)
            {
                Logger.Debug(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType());
                hook.PostCommit(commit);
            }
            return commit;
        }
        public virtual bool PreCommit(CommitAttempt attempt)
        {
            Logger.Debug(Resources.OptimisticConcurrencyCheck, attempt.StreamId);

            ICommit head = GetStreamHead(attempt.StreamId);

            if (head == null)
            {
                return(true);
            }

            if (head.CommitSequence >= attempt.CommitSequence)
            {
                throw new ConcurrencyException();
            }

            if (head.StreamRevision >= attempt.StreamRevision)
            {
                throw new ConcurrencyException();
            }

            if (head.CommitSequence < attempt.CommitSequence - 1)
            {
                throw new StorageException(); // beyond the end of the stream
            }

            if (head.StreamRevision < attempt.StreamRevision - attempt.Events.Count)
            {
                throw new StorageException(); // beyond the end of the stream
            }

            Logger.Debug(Resources.NoConflicts, attempt.StreamId);
            return(true);
        }
示例#5
0
            protected override Task Context()
            {
                Committed = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                Attempt   = BuildCommitAttemptStub(HeadStreamRevision + 1, DupliateCommitSequence);

                return(Hook.PostCommit(Committed));
            }
示例#6
0
        public virtual ICommit Commit(CommitAttempt attempt)
        {
            Guard.NotNull(() => attempt, attempt);
            foreach (var hook in _pipelineHooks)
            {
                Logger.Debug(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType());
                if (hook.PreCommit(attempt))
                {
                    continue;
                }

                Logger.Info(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId);
                return(null);
            }

            Logger.Info(Resources.CommittingAttempt, attempt.CommitId, attempt.Events.Count);
            ICommit commit = _persistence.Commit(attempt);

            foreach (var hook in _pipelineHooks)
            {
                Logger.Debug(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType());
                hook.PostCommit(commit);
            }
            return(commit);
        }
示例#7
0
            protected override Task Context()
            {
                _committed     = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                _failedAttempt = BuildCommitAttemptStub(DuplicateStreamRevision, HeadCommitSequence + 1);

                return(Hook.PostCommit(_committed));
            }
            protected override Task Context()
            {
                _alreadyCommitted = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                _beyondEndOfStream = BuildCommitAttemptStub(HeadStreamRevision + 1, BeyondEndOfStreamCommitSequence);

                return Hook.PostCommit(_alreadyCommitted);
            }
        protected override void Context()
        {
            _alreadyCommitted = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
            _beyondEndOfStream = BuildCommitAttemptStub(BeyondEndOfStreamRevision, HeadCommitSequence + 1);

            Hook.PostCommit(_alreadyCommitted);
        }
示例#10
0
            protected override Task Context()
            {
                _successfulAttempt = BuildCommitStub(1, DuplicateCommitSequence);
                _failedAttempt     = BuildCommitAttemptStub(2, DuplicateCommitSequence);

                return(Hook.PostCommitAsync(_successfulAttempt, CancellationToken.None));
            }
示例#11
0
            protected override Task Context()
            {
                _alreadyCommitted  = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                _beyondEndOfStream = BuildCommitAttemptStub(HeadStreamRevision + 1, BeyondEndOfStreamCommitSequence);

                return(Hook.PostCommitAsync(_alreadyCommitted, CancellationToken.None));
            }
示例#12
0
            protected override Task Context()
            {
                _alreadyCommitted  = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                _beyondEndOfStream = BuildCommitAttemptStub(BeyondEndOfStreamRevision, HeadCommitSequence + 1);

                return(Hook.PostCommit(_alreadyCommitted));
            }
示例#13
0
        protected override void Context()
        {
            _populatedAttempt = BuildCommitAttemptStub(1, 1);

            A.CallTo(() => Persistence.Commit(_populatedAttempt))
            .ReturnsLazily((CommitAttempt attempt) =>
            {
                _populatedCommit = new Commit(attempt.BucketId,
                                              attempt.StreamId,
                                              attempt.StreamRevision,
                                              attempt.CommitId,
                                              attempt.CommitSequence,
                                              attempt.CommitStamp,
                                              new LongCheckpoint(0).Value,
                                              attempt.Headers,
                                              attempt.Events);
                return(_populatedCommit);
            });

            var hook = A.Fake <IPipelineHook>();

            A.CallTo(() => hook.PreCommit(_populatedAttempt)).Returns(true);

            PipelineHooks.Add(hook);
        }
示例#14
0
 protected override Task Context()
 {
     _attempt = new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, DateTime.Now, null, new List <EventMessage> {
         new EventMessage()
     });
     return(Task.FromResult(true));
 }
        protected override Task Context()
        {
            _populatedAttempt = BuildCommitAttemptStub(1, 1);

            A.CallTo(() => Persistence.CommitAsync(_populatedAttempt, A <CancellationToken> ._))
            .ReturnsLazily((CommitAttempt attempt) =>
            {
                _populatedCommit = new Commit(attempt.BucketId,
                                              attempt.StreamId,
                                              attempt.StreamRevision,
                                              attempt.CommitId,
                                              attempt.CommitSequence,
                                              attempt.CommitStamp,
                                              0,
                                              attempt.Headers,
                                              attempt.Events);
                return(_populatedCommit);
            });

            var hook = A.Fake <IPipelineHook>();

            A.CallTo(() => hook.PreCommitAsync(_populatedAttempt, A <CancellationToken> ._)).Returns(true);

            PipelineHooks.Add(hook);
            return(Task.CompletedTask);
        }
示例#16
0
            protected override Task Context()
            {
                _successfulAttempt = BuildCommitStub(1, DuplicateCommitSequence);
                _failedAttempt     = BuildCommitAttemptStub(2, DuplicateCommitSequence);

                return(Hook.PostCommit(_successfulAttempt));
            }
示例#17
0
            protected override Task Context()
            {
                Committed = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
                Attempt   = BuildCommitAttemptStub(HeadStreamRevision + 1, DupliateCommitSequence);

                return(Hook.PostCommitAsync(Committed, CancellationToken.None));
            }
示例#18
0
            protected override Task Context()
            {
                _successfulAttempt = BuildCommitStub(DuplicateStreamRevision, 1);
                _failedAttempt     = BuildCommitAttemptStub(DuplicateStreamRevision, 2);

                return(Hook.PostCommit(_successfulAttempt));
            }
            protected override void Context()
            {
                _successfulAttempt = BuildCommitStub(1, DuplicateStreamRevision, 1);
                _failedAttempt     = BuildCommitAttemptStub(DuplicateStreamRevision, 2);

                Hook.PostCommit(_successfulAttempt);
            }
示例#20
0
        public override Task <bool> PreCommit(CommitAttempt attempt)
        {
            Logger.Debug(Resources.OptimisticConcurrencyCheck, attempt.StreamId);

            ICommit head = GetStreamHead(GetHeadKey(attempt));

            if (head != null)
            {
                if (head.CommitSequence >= attempt.CommitSequence)
                {
                    throw new ConcurrencyException();
                }

                if (head.StreamRevision >= attempt.StreamRevision)
                {
                    throw new ConcurrencyException();
                }

                if (head.CommitSequence < attempt.CommitSequence - 1)
                {
                    throw new StorageException();                     // beyond the end of the stream
                }

                if (head.StreamRevision < attempt.StreamRevision - attempt.Events.Count)
                {
                    throw new StorageException();                     // beyond the end of the stream
                }

                Logger.Debug(Resources.NoConflicts, attempt.StreamId);
            }
            return(Task.FromResult(true));
        }
示例#21
0
            protected override Task Context()
            {
                _successfulAttempt = BuildCommitStub(DuplicateStreamRevision, 1);
                _failedAttempt     = BuildCommitAttemptStub(DuplicateStreamRevision, 2);

                return(Hook.PostCommitAsync(_successfulAttempt, CancellationToken.None));
            }
        public virtual bool PreCommit(CommitAttempt attempt)
        {
            Logger.Debug(Resources.OptimisticConcurrencyCheck, attempt.StreamId);

            ICommit head = GetStreamHead(attempt.StreamId);
            if (head == null)
            {
                return true;
            }

            if (head.CommitSequence >= attempt.CommitSequence)
            {
                throw new ConcurrencyException();
            }

            if (head.StreamRevision >= attempt.StreamRevision)
            {
                throw new ConcurrencyException();
            }

            if (head.CommitSequence < attempt.CommitSequence - 1)
            {
                throw new StorageException(); // beyond the end of the stream
            }

            if (head.StreamRevision < attempt.StreamRevision - attempt.Events.Count)
            {
                throw new StorageException(); // beyond the end of the stream
            }

            Logger.Debug(Resources.NoConflicts, attempt.StreamId);
            return true;
        }
        protected override void Context()
        {
            _attempt = BuildCommitAttemptStub(1, 1);
            _commit  = BuildCommitStub(1, 1);

            PipelineHooks.Add(new Mock <IPipelineHook>());
            PipelineHooks[0].Setup(x => x.PreCommit(_attempt)).Returns(false);
        }
示例#24
0
        private void PersistChanges(Guid commitId)
        {
            CommitAttempt attempt = BuildCommitAttempt(commitId);

            Logger.Debug(Resources.PersistingCommit, commitId, StreamId);
            ICommit commit = _persistence.Commit(attempt);

            PopulateStream(StreamRevision + 1, attempt.StreamRevision, new[] { commit });
            ClearChanges();
        }
示例#25
0
        protected override void Context()
        {
            _attempt = BuildCommitAttemptStub(1, 1);
            _commit  = BuildCommitStub(1, 1);

            var hook = A.Fake <IPipelineHook>();

            A.CallTo(() => hook.PreCommit(_attempt)).Returns(false);

            PipelineHooks.Add(hook);
        }
        protected override Task Context()
        {
            _attempt = BuildCommitAttemptStub(1, 1);
            _commit  = BuildCommitStub(1, 1);

            var hook = A.Fake <IPipelineHook>();

            A.CallTo(() => hook.PreCommitAsync(_attempt, A <CancellationToken> ._)).Returns(false);

            PipelineHooks.Add(hook);
            return(Task.CompletedTask);
        }
 public void Put(SourceCommitMessage sourceCommit)
 {
     var commitAttempt = new CommitAttempt(
         sourceCommit.StreamId,
         sourceCommit.StreamRevision,
         sourceCommit.CommitId,
         sourceCommit.CommitSequence,
         sourceCommit.CommitStamp,
         sourceCommit.Headers,
         sourceCommit.Events.Select(s => new EventMessage{ Headers = DeserializeHeaders(s.Headers), Body = DeserializeBody(s) }).ToArray());
     _store.Advanced.Commit(commitAttempt);
 }
 public static ICommit ToCommit(this CommitAttempt attempt, Int64 checkpointToken)
 {
     return(new Commit(
                attempt.BucketId,
                attempt.StreamId,
                attempt.StreamRevision,
                attempt.CommitId,
                attempt.CommitSequence,
                attempt.CommitStamp,
                checkpointToken,
                attempt.Headers,
                attempt.Events));
 }
示例#29
0
        private async Task PersistChanges(Guid commitId)
        {
            CommitAttempt attempt = BuildCommitAttempt(commitId);

            Logger.Debug(Resources.PersistingCommit, commitId, StreamId);
            ICommit commit = await _persistence.Commit(attempt);

            if (commit != null)
            {
                await PopulateStream(StreamRevision + 1, attempt.StreamRevision, AsyncEnumerable.Create(commit));
            }

            ClearChanges();
        }
示例#30
0
        protected override Task Context()
        {
            _attempt = BuildCommitAttemptStub(1, 1);
            _commit  = BuildCommitStub(1, 1);

            //var hook = A.Fake<IPipelineHook>();
            //A.CallTo(() => hook.PreCommit(_attempt)).Returns(false);
            var hook = Substitute.For <IPipelineHook>();

            hook.PreCommit(_attempt).Returns(false);

            PipelineHooks.Add(hook);
            return(Task.FromResult(true));
        }
示例#31
0
        protected override Task Context()
        {
            _populatedAttempt = BuildCommitAttemptStub(1, 1);

            Persistence.Commit(_populatedAttempt)
            .Returns(callInfo =>
            {
                var attempt      = callInfo.Arg <CommitAttempt>();
                _populatedCommit = new Commit(attempt.BucketId,
                                              attempt.StreamId,
                                              attempt.StreamRevision,
                                              attempt.CommitId,
                                              attempt.CommitSequence,
                                              attempt.CommitStamp,
                                              new LongCheckpoint(0).Value,
                                              attempt.Headers,
                                              attempt.Events);
                return(_populatedCommit);
            });

            //A.CallTo(() => Persistence.Commit(_populatedAttempt))
            //    .ReturnsLazily((CommitAttempt attempt) =>
            //    {
            //        _populatedCommit = new Commit(attempt.BucketId,
            //            attempt.StreamId,
            //            attempt.StreamRevision,
            //            attempt.CommitId,
            //            attempt.CommitSequence,
            //            attempt.CommitStamp,
            //            new LongCheckpoint(0).Value,
            //            attempt.Headers,
            //            attempt.Events);
            //        return _populatedCommit;
            //    });

            //var hook = A.Fake<IPipelineHook>();
            //A.CallTo(() => hook.PreCommit(_populatedAttempt)).Returns(true);
            var hook = Substitute.For <IPipelineHook>();

            hook.PreCommit(_populatedAttempt).Returns(true);

            PipelineHooks.Add(hook);
            return(Task.FromResult(true));
        }
示例#32
0
 protected override void Context()
 {
     Persistence
     .Setup(x => x.Commit(It.IsAny <CommitAttempt>()))
     .Callback <CommitAttempt>(x => _constructed = x)
     .Returns((CommitAttempt attempt) => new Commit(
                  attempt.BucketId, attempt.StreamId,
                  attempt.StreamRevision,
                  attempt.CommitId,
                  attempt.CommitSequence,
                  attempt.CommitStamp,
                  new IntCheckpoint(0).Value,
                  attempt.Headers,
                  attempt.Events));
     Stream.Add(_uncommitted);
     foreach (var item in _headers)
     {
         Stream.UncommittedHeaders[item.Key] = item.Value;
     }
 }
 protected override void Context()
 {
     A.CallTo(() => Persistence.Commit(A <CommitAttempt> ._))
     .Invokes((CommitAttempt _) => _constructed = _)
     .ReturnsLazily((CommitAttempt attempt) => new Commit(
                        attempt.BucketId,
                        attempt.StreamId,
                        attempt.StreamRevision,
                        attempt.CommitId,
                        attempt.CommitSequence,
                        attempt.CommitStamp,
                        0,
                        attempt.Headers,
                        attempt.Events));
     Stream.Add(_uncommitted);
     foreach (var item in _headers)
     {
         Stream.UncommittedHeaders[item.Key] = item.Value;
     }
 }
示例#34
0
        protected override Task Context()
        {
            Persistence
            .Commit(Arg.Any <CommitAttempt>())
            .Returns(c =>
            {
                var attempt  = c.Arg <CommitAttempt>();
                _constructed = attempt;
                return(new Commit(
                           attempt.BucketId,
                           attempt.StreamId,
                           attempt.StreamRevision,
                           attempt.CommitId,
                           attempt.CommitSequence,
                           attempt.CommitStamp,
                           new LongCheckpoint(0).Value,
                           attempt.Headers,
                           attempt.Events
                           ));
            });

            //A.CallTo(() => Persistence.Commit(A<CommitAttempt>._))
            //    .Invokes((CommitAttempt _) => _constructed = _)
            //    .ReturnsLazily((CommitAttempt attempt) => new Commit(
            //        attempt.BucketId,
            //        attempt.StreamId,
            //        attempt.StreamRevision,
            //        attempt.CommitId,
            //        attempt.CommitSequence,
            //        attempt.CommitStamp,
            //        new LongCheckpoint(0).Value,
            //        attempt.Headers,
            //        attempt.Events));
            Stream.Add(_uncommitted);
            foreach (var item in _headers)
            {
                Stream.UncommittedHeaders[item.Key] = item.Value;
            }
            return(Task.FromResult(true));
        }
        protected override void Context()
        {
            _populatedAttempt = BuildCommitAttemptStub(1, 1);

            Persistence.Setup(x => x.Commit(_populatedAttempt))
            .Returns((CommitAttempt attempt) =>
            {
                _populatedCommit = new Commit(attempt.BucketId,
                                              attempt.StreamId,
                                              attempt.StreamRevision,
                                              attempt.CommitId,
                                              attempt.CommitSequence,
                                              attempt.CommitStamp,
                                              new IntCheckpoint(0).Value,
                                              attempt.Headers,
                                              attempt.Events);
                return(_populatedCommit);
            });

            PipelineHooks.Add(new Mock <IPipelineHook>());
            PipelineHooks[0].Setup(x => x.PreCommit(_populatedAttempt)).Returns(true);
            PipelineHooks[0].Setup(x => x.PostCommit(_populatedCommit));
        }
 protected override Task Context()
 {
     _attempt = new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, DateTime.Now, null, new List<EventMessage> {new EventMessage()});
     return Task.FromResult(true);
 }
        protected override void Context()
        {
            Committed = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
            Attempt = BuildCommitAttemptStub(HeadStreamRevision + 1, DupliateCommitSequence);

            Hook.PostCommit(Committed);
        }
        protected override void Context()
        {
            _populatedAttempt = BuildCommitAttemptStub(1, 1);

            A.CallTo(() => Persistence.Commit(_populatedAttempt))
                .ReturnsLazily((CommitAttempt attempt) =>
                {
                    _populatedCommit = new Commit(attempt.BucketId,
                        attempt.StreamId,
                        attempt.StreamRevision,
                        attempt.CommitId,
                        attempt.CommitSequence,
                        attempt.CommitStamp,
                        new LongCheckpoint(0).Value,
                        attempt.Headers,
                        attempt.Events);
                    return _populatedCommit;
                });

            var hook = A.Fake<IPipelineHook>();
            A.CallTo(() => hook.PreCommit(_populatedAttempt)).Returns(true);

            PipelineHooks.Add(hook);
        }
        protected override Task Context()
        {
            _attempt = BuildCommitAttemptStub(1, 1);
            _commit = BuildCommitStub(1, 1);

            //var hook = A.Fake<IPipelineHook>();
            //A.CallTo(() => hook.PreCommit(_attempt)).Returns(false);
            var hook = Substitute.For<IPipelineHook>();
            hook.PreCommit(_attempt).Returns(false);

            PipelineHooks.Add(hook);
			return Task.FromResult(true);
        }
        protected override void Context()
        {
            _successfulAttempt = BuildCommitStub(1, DuplicateCommitSequence);
            _failedAttempt = BuildCommitAttemptStub(2, DuplicateCommitSequence);

            Hook.PostCommit(_successfulAttempt);
        }
 public bool PreCommit(CommitAttempt attempt)
 {
     // Can easily do logging or other such activities here
     return true; // true == allow commit to continue, false = stop.
 }
 protected override void Context()
 {
     _attempt = new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, DateTime.Now, null, new List<EventMessage>{ new EventMessage() });
 }
        protected override void Context()
        {
            _successfulAttempt = BuildCommitStub(DuplicateStreamRevision, 1);
            _failedAttempt = BuildCommitAttemptStub(DuplicateStreamRevision, 2);

            Hook.PostCommit(_successfulAttempt);
        }
            protected override void Context()
            {
                _succesfulAttempt = BuildCommitStub(3, 1);
                _failedAttempt = BuildCommitAttemptStub(4, 2, 2);

                Hook.PostCommit(_succesfulAttempt);
            }
        protected override void Context()
        {
            _committed = BuildCommitStub(HeadStreamRevision, HeadCommitSequence);
            _failedAttempt = BuildCommitAttemptStub(DuplicateStreamRevision, HeadCommitSequence + 1);

            Hook.PostCommit(_committed);
        }
        protected override Task Context()
        {
            _populatedAttempt = BuildCommitAttemptStub(1, 1);

            Persistence.Commit(_populatedAttempt)
                .Returns(callInfo =>
                {
                    var attempt = callInfo.Arg<CommitAttempt>();
                    _populatedCommit = new Commit(attempt.BucketId,
                        attempt.StreamId,
                        attempt.StreamRevision,
                        attempt.CommitId,
                        attempt.CommitSequence,
                        attempt.CommitStamp,
                        new LongCheckpoint(0).Value,
                        attempt.Headers,
                        attempt.Events);
                    return _populatedCommit;
                });

            //A.CallTo(() => Persistence.Commit(_populatedAttempt))
            //    .ReturnsLazily((CommitAttempt attempt) =>
            //    {
            //        _populatedCommit = new Commit(attempt.BucketId,
            //            attempt.StreamId,
            //            attempt.StreamRevision,
            //            attempt.CommitId,
            //            attempt.CommitSequence,
            //            attempt.CommitStamp,
            //            new LongCheckpoint(0).Value,
            //            attempt.Headers,
            //            attempt.Events);
            //        return _populatedCommit;
            //    });

            //var hook = A.Fake<IPipelineHook>();
            //A.CallTo(() => hook.PreCommit(_populatedAttempt)).Returns(true);
            var hook = Substitute.For<IPipelineHook>();
            hook.PreCommit(_populatedAttempt).Returns(true);

            PipelineHooks.Add(hook);
			return Task.FromResult(true);
        }
 public virtual Task<bool> PreCommit(CommitAttempt attempt)
 {
     return Task.FromResult(true);
 }
        protected override void Context()
        {
            _attempt = BuildCommitAttemptStub(1, 1);
            _commit = BuildCommitStub(1, 1);

            var hook = A.Fake<IPipelineHook>();
            A.CallTo(() => hook.PreCommit(_attempt)).Returns(false);

            PipelineHooks.Add(hook);
        }
 public bool PreCommit(CommitAttempt attempt)
 {
     return true;
 }