Пример #1
0
 internal SnapshotExchange(long term, IRaftLogEntry snapshot, long snapshotIndex, PipeOptions?options = null)
 {
     this.term          = term;
     this.snapshotIndex = snapshotIndex;
     this.snapshot      = snapshot;
     pipe = new Pipe(options ?? PipeOptions.Default);
 }
Пример #2
0
        private void Append(IRaftLogEntry[] entries, long startIndex)
        {
            if (startIndex < log.LongLength)
            {
                log = log.RemoveLast(log.LongLength - startIndex);
            }
            var newLog = new IRaftLogEntry[entries.Length + log.LongLength];

            Array.Copy(log, newLog, log.LongLength);
            entries.CopyTo(newLog, log.LongLength);
            log = newLog;
        }
Пример #3
0
        private static async ValueTask <IRaftLogEntry[]> ReadAllAsync <TEntry>(ILogEntryProducer <TEntry> entries, CancellationToken token)
            where TEntry : IRaftLogEntry
        {
            var bufferedEntries = new IRaftLogEntry[entries.RemainingCount];

            for (var i = 0L; await entries.MoveNextAsync().ConfigureAwait(false); i++)
            {
                bufferedEntries[i] = entries.Current.IsReusable ?
                                     (IRaftLogEntry)entries.Current :
                                     await BufferedLogEntry.CreateBufferedEntryAsync(entries.Current, token).ConfigureAwait(false);
            }
            return(bufferedEntries);
        }
Пример #4
0
        /// <summary>
        /// Initializes a new persistent audit trail.
        /// </summary>
        /// <param name="path">The path to the folder to be used by audit trail.</param>
        /// <param name="recordsPerPartition">The maximum number of log entries that can be stored in the single file called partition.</param>
        /// <param name="configuration">The configuration of the persistent audit trail.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="recordsPerPartition"/> is less than 2.</exception>
        public PersistentState(DirectoryInfo path, int recordsPerPartition, Options?configuration = null)
        {
            if (configuration is null)
            {
                configuration = new Options();
            }
            if (recordsPerPartition < 2L)
            {
                throw new ArgumentOutOfRangeException(nameof(recordsPerPartition));
            }
            if (!path.Exists)
            {
                path.Create();
            }
            backupCompression        = configuration.BackupCompression;
            replayOnInitialize       = configuration.ReplayOnInitialize;
            bufferSize               = configuration.BufferSize;
            location                 = path;
            this.recordsPerPartition = recordsPerPartition;
            initialSize              = configuration.InitialPartitionSize;
            commitEvent              = new AsyncManualResetEvent(false);
            sessionManager           = new DataAccessSessionManager(configuration.MaxConcurrentReads, configuration.GetMemoryAllocator <byte>(), bufferSize);
            syncRoot                 = new AsyncSharedLock(sessionManager.Capacity);
            entryPool                = configuration.GetMemoryAllocator <LogEntry>();
            metadataPool             = configuration.UseCaching ? configuration.GetMemoryAllocator <LogEntryMetadata>() : null;
            nullSegment              = new StreamSegment(Stream.Null);
            initialEntry             = new LogEntry(nullSegment, sessionManager.WriteSession.Buffer, new LogEntryMetadata());

            // sorted dictionary to improve performance of log compaction and snapshot installation procedures
            partitionTable = new SortedDictionary <long, Partition>();

            // load all partitions from file system
            foreach (var file in path.EnumerateFiles())
            {
                if (long.TryParse(file.Name, out var partitionNumber))
                {
                    var partition = new Partition(file.Directory, bufferSize, recordsPerPartition, partitionNumber, metadataPool, sessionManager.Capacity);
                    partition.PopulateCache(sessionManager.WriteSession);
                    partitionTable[partitionNumber] = partition;
                }
            }

            state    = new NodeState(path, AsyncLock.Exclusive(syncRoot));
            snapshot = new Snapshot(path, bufferSize, sessionManager.Capacity);
            snapshot.PopulateCache(sessionManager.WriteSession);
        }
Пример #5
0
 Task <Result <bool> > IRaftClusterMember.InstallSnapshotAsync(long term, IRaftLogEntry snapshot, long snapshotIndex, CancellationToken token)
 => throw new NotImplementedException();
Пример #6
0
 private protected override Task <Result <bool> > InstallSnapshotAsync(long term, IRaftLogEntry snapshot, long snapshotIndex, CancellationToken token)
 => SendAsync <Result <bool>, SnapshotExchange>(new SnapshotExchange(term, snapshot, snapshotIndex, pipeConfig), token);
Пример #7
0
 private InstallSnapshotMessage(HeadersReader <StringValues> headers, Stream body)
     : base(headers)
 {
     Index    = ParseHeader(SnapshotIndexHeader, headers, Int64Parser);
     Snapshot = new ReceivedSnapshot(body, ParseHeader(SnapshotTermHeader, headers, Int64Parser), ParseHeader(HeaderNames.LastModified, headers, DateTimeParser));
 }
Пример #8
0
 internal InstallSnapshotMessage(IPEndPoint sender, long term, long index, IRaftLogEntry snapshot)
     : base(MessageType, sender, term)
 {
     Index    = index;
     Snapshot = snapshot;
 }
Пример #9
0
 /// <summary>
 /// Applies the command represented by the log entry to the underlying database engine.
 /// </summary>
 /// <param name="entry">The entry to be applied to the state machine.</param>
 /// <returns>The task representing asynchronous execution of this method.</returns>
 protected virtual ValueTask ApplyAsync(IRaftLogEntry entry) => new ValueTask();