示例#1
0
        //true if at least one entry from current term is stored on this node; otherwise, false
        private static async Task <Result <bool> > AppendEntriesAsync(IRaftClusterMember member, long commitIndex,
                                                                      long term,
                                                                      IAuditTrail <ILogEntry> transactionLog, ILogger logger, CancellationToken token)
        {
            var currentIndex = transactionLog.GetLastIndex(false);

            logger.ReplicationStarted(member.Endpoint, currentIndex);
            var precedingIndex = Math.Max(0, member.NextIndex - 1);
            var precedingTerm  = (await transactionLog.GetEntryAsync(precedingIndex).ConfigureAwait(false) ??
                                  transactionLog.First).Term;
            var entries = currentIndex >= member.NextIndex
                ? await transactionLog.GetEntriesAsync(member.NextIndex).ConfigureAwait(false)
                : Array.Empty <ILogEntry>();

            logger.ReplicaSize(member.Endpoint, entries.Count, precedingIndex, precedingTerm);
            //trying to replicate
            var result = await member
                         .AppendEntriesAsync(term, entries, precedingIndex, precedingTerm, commitIndex, token)
                         .ConfigureAwait(false);

            if (result.Value)
            {
                logger.ReplicationSuccessful(member.Endpoint, member.NextIndex);
                member.NextIndex.VolatileWrite(currentIndex + 1);
                //checks whether the at least one entry from current term is stored on this node
                result = result.SetValue(entries.Any(entry => entry.Term == term));
            }
            else
            {
                logger.ReplicationFailed(member.Endpoint, member.NextIndex.DecrementAndGet());
            }

            return(result);
        }
示例#2
0
        internal static async ValueTask <LogEntry> GetEntryAsync <LogEntry>(this IAuditTrail <LogEntry> auditTrail, long index)
            where LogEntry : class, IMessage

        {
            var entries = await auditTrail.GetEntriesAsync(index, index).ConfigureAwait(false);

            return(entries.Count > 0 ? entries[0] : null);
        }
示例#3
0
        private static async void OnCommitted(IAuditTrail <ILogEntry> sender, long startIndex, long count)
        {
            foreach (var entry in await sender.GetEntriesAsync(startIndex, startIndex + count).ConfigureAwait(false))
            {
                var content = await entry.ReadAsTextAsync().ConfigureAwait(false);

                Console.WriteLine($"Message '{content}' is committed at term {entry.Term}");
            }
        }