コード例 #1
0
        public void Apply(TransactionOperationContext context, long uptoInclusive, Leader leader, ServerStore serverStore)
        {
            Debug.Assert(context.Transaction != null);

            var lastAppliedIndex = _parent.GetLastCommitIndex(context);

            for (var index = lastAppliedIndex + 1; index <= uptoInclusive; index++)
            {
                var cmd = _parent.GetEntry(context, index, out RachisEntryFlags flags);
                if (cmd == null || flags == RachisEntryFlags.Invalid)
                {
                    throw new InvalidOperationException("Expected to apply entry " + index + " but it isn't stored");
                }

                if (flags != RachisEntryFlags.StateMachineCommand)
                {
                    continue;
                }

                Apply(context, cmd, index, leader, serverStore);
            }
            var term = _parent.GetTermForKnownExisting(context, uptoInclusive);

            _parent.SetLastCommitIndex(context, uptoInclusive, term);
        }
コード例 #2
0
        public long Apply(ClusterOperationContext context, long uptoInclusive, Leader leader, ServerStore serverStore, Stopwatch duration)
        {
            Debug.Assert(context.Transaction != null);

            var lastAppliedIndex             = _parent.GetLastCommitIndex(context);
            var maxTimeAllowedToWaitForApply = _parent.Timeout.TimeoutPeriod / 4;

            for (var index = lastAppliedIndex + 1; index <= uptoInclusive; index++)
            {
                var cmd = _parent.GetEntry(context, index, out RachisEntryFlags flags);
                if (cmd == null || flags == RachisEntryFlags.Invalid)
                {
                    throw new InvalidOperationException("Expected to apply entry " + index + " but it isn't stored");
                }

                lastAppliedIndex = index;

                if (flags != RachisEntryFlags.StateMachineCommand)
                {
                    _parent.LogHistory.UpdateHistoryLog(context, index, _parent.CurrentTerm, cmd, null, null);

                    var currentIndex = index;
                    context.Transaction.InnerTransaction.LowLevelTransaction.OnDispose += t =>
                    {
                        if (t is LowLevelTransaction llt && llt.Committed)
                        {
                            serverStore.Cluster.NotifyAndSetCompleted(currentIndex);
                        }
                    };
                    continue;
                }

                Apply(context, cmd, index, leader, serverStore);

                if (duration.ElapsedMilliseconds >= maxTimeAllowedToWaitForApply)
                {
                    // we don't want to spend so much time applying commands that we will time out the leader
                    // so we time this from the follower perspective and abort after applying a single command
                    // or 25% of the time has already passed
                    break;
                }
            }
            var term = _parent.GetTermForKnownExisting(context, lastAppliedIndex);

            _parent.SetLastCommitIndex(context, lastAppliedIndex, term);

            return(lastAppliedIndex);
        }