private async Task Restore() { TransactionalStorageLoadResponse <TState> loadresponse = await storage.Load(); this.storageBatch = new StorageBatch <TState>(loadresponse); this.stableState = loadresponse.CommittedState; this.stableSequenceNumber = loadresponse.CommittedSequenceId; if (logger.IsEnabled(LogLevel.Debug)) { logger.Debug($"Load v{this.stableSequenceNumber} {loadresponse.PendingStates.Count}p {storageBatch.MetaData.CommitRecords.Count}c"); } // ensure clock is consistent with loaded state this.Clock.Merge(storageBatch.MetaData.TimeStamp); // resume prepared transactions (not TM) foreach (var pr in loadresponse.PendingStates.OrderBy(ps => ps.TimeStamp)) { if (pr.SequenceId > loadresponse.CommittedSequenceId && pr.TransactionManager.Reference != null) { if (logger.IsEnabled(LogLevel.Debug)) { logger.Debug($"recover two-phase-commit {pr.TransactionId}"); } ParticipantId tm = pr.TransactionManager; commitQueue.Add(new TransactionRecord <TState>() { Role = CommitRole.RemoteCommit, TransactionId = Guid.Parse(pr.TransactionId), Timestamp = pr.TimeStamp, State = pr.State, SequenceNumber = pr.SequenceId, TransactionManager = tm, PrepareIsPersisted = true, LastSent = default(DateTime), ConfirmationResponsePromise = null, NumberWrites = 1 // was a writing transaction }); this.stableSequenceNumber = pr.SequenceId; } } // resume committed transactions (on TM) foreach (var kvp in storageBatch.MetaData.CommitRecords) { if (logger.IsEnabled(LogLevel.Debug)) { logger.Debug($"recover commit confirmation {kvp.Key}"); } this.confirmationWorker.Add(kvp.Key, kvp.Value.Timestamp, kvp.Value.WriteParticipants); } // check for work this.storageWorker.Notify(); this.RWLock.Notify(); }
private async Task DoLoad() { this.logger.Debug("DoLoad"); // load inital state TransactionalStorageLoadResponse <TState> loadResponse = await this.storage.Load(StateName); this.eTag = loadResponse.ETag; this.metadata = Metadata.FromString(loadResponse.Metadata); this.version = this.metadata.HighestVersion; this.highestReadTransactionId = this.metadata.HighestReadTransactionId; this.commitedState = loadResponse.CommittedState; foreach (PendingTransactionState <TState> pendingState in loadResponse.PendingStates) { if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.Debug("Rebuilding log from storage for {0}", pendingState.SequenceId); } this.log[pendingState.SequenceId] = new LogRecord <TState> { NewVal = pendingState.State, Version = (TransactionalResourceVersion.TryParse(pendingState.TransactionId, out TransactionalResourceVersion version)) ? version : default(TransactionalResourceVersion) }; } UpdateActiveState(); }
public StorageBatch(TransactionalStorageLoadResponse <TState> loadresponse) { MetaData = ReadMetaData(loadresponse); ETag = loadresponse.ETag; confirmUpTo = loadresponse.CommittedSequenceId; cancelAbove = loadresponse.PendingStates.LastOrDefault()?.SequenceId ?? loadresponse.CommittedSequenceId; cancelAboveStart = cancelAbove; }
public StorageBatch(TransactionalStorageLoadResponse <TState> loadresponse, JsonSerializerSettings serializerSettings) { this.serializerSettings = serializerSettings ?? throw new ArgumentNullException(nameof(serializerSettings)); MetaData = ReadMetaData(loadresponse, this.serializerSettings); ETag = loadresponse.ETag; confirmUpTo = loadresponse.CommittedSequenceId; cancelAbove = loadresponse.PendingStates.LastOrDefault()?.SequenceId ?? loadresponse.CommittedSequenceId; cancelAboveStart = cancelAbove; }
private static MetaData ReadMetaData(TransactionalStorageLoadResponse <TState> loadresponse) { if (string.IsNullOrEmpty(loadresponse.Metadata)) { // this thing is fresh... did not exist in storage yet return(new MetaData() { TimeStamp = default(DateTime), CommitRecords = new Dictionary <Guid, CommitRecord>(), }); } else { return(JsonConvert.DeserializeObject <MetaData>(loadresponse.Metadata, MetaData.SerializerSettings)); } }
private async Task DoRecovery() { // load inital state TransactionalStorageLoadResponse <TState> loadResponse = await this.storage.Load(StateName); this.eTag = loadResponse.ETag; this.metadata = Metadata.FromString(loadResponse.Metadata); this.highestReadTransactionId = this.metadata.HighestReadTransactionId; this.version = this.metadata.HighestVersion; this.value = loadResponse.CommittedState; this.log.Clear(); foreach (PendingTransactionState <TState> pendingState in loadResponse.PendingStates) { this.log[pendingState.SequenceId] = new LogRecord <TState> { NewVal = pendingState.State, Version = (TransactionalResourceVersion.TryParse(pendingState.TransactionId, out TransactionalResourceVersion version)) ? version : default(TransactionalResourceVersion) }; } // Rollback any known aborted transactions Restore(); }
public StorageBatch(TransactionalStorageLoadResponse <TState> loadresponse) : this(loadresponse.Metadata, loadresponse.ETag, loadresponse.CommittedSequenceId, loadresponse.PendingStates.LastOrDefault()?.SequenceId ?? loadresponse.CommittedSequenceId) { }