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); }
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; }
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); }
/// <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); }
Task <Result <bool> > IRaftClusterMember.InstallSnapshotAsync(long term, IRaftLogEntry snapshot, long snapshotIndex, CancellationToken token) => throw new NotImplementedException();
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);
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)); }
internal InstallSnapshotMessage(IPEndPoint sender, long term, long index, IRaftLogEntry snapshot) : base(MessageType, sender, term) { Index = index; Snapshot = snapshot; }
/// <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();