Example #1
0
        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();
        }
Example #2
0
        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();
        }
Example #3
0
 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;
 }
Example #5
0
 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));
     }
 }
Example #6
0
        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();
        }
Example #7
0
 public StorageBatch(TransactionalStorageLoadResponse <TState> loadresponse)
     : this(loadresponse.Metadata, loadresponse.ETag, loadresponse.CommittedSequenceId, loadresponse.PendingStates.LastOrDefault()?.SequenceId ?? loadresponse.CommittedSequenceId)
 {
 }