Exemplo n.º 1
0
        public void RecordWrite(ParticipantId id, DateTime minTime)
        {
            this.Participants.TryGetValue(id, out AccessCounter count);

            count.Writes++;

            this.Participants[id] = count;

            if (minTime > TimeStamp)
            {
                TimeStamp = minTime;
            }
        }
Exemplo n.º 2
0
        private void CollateParticipants(Dictionary <ParticipantId, AccessCounter> participants, out List <ParticipantId> writers, out List <KeyValuePair <ParticipantId, AccessCounter> > resources, out KeyValuePair <ParticipantId, AccessCounter>?manager)
        {
            writers   = null;
            resources = null;
            manager   = null;
            KeyValuePair <ParticipantId, AccessCounter>?priorityManager = null;

            foreach (KeyValuePair <ParticipantId, AccessCounter> participant in participants)
            {
                ParticipantId id = participant.Key;
                // priority manager
                if (id.IsPriorityManager())
                {
                    manager = priorityManager = (priorityManager == null)
                        ? participant
                        : throw new ArgumentOutOfRangeException(nameof(participants), "Only one priority transaction manager allowed in transaction");
                }
                // resource
                if (id.IsResource())
                {
                    if (resources == null)
                    {
                        resources = new List <KeyValuePair <ParticipantId, AccessCounter> >();
                    }
                    resources.Add(participant);
                    if (participant.Value.Writes > 0)
                    {
                        if (writers == null)
                        {
                            writers = new List <ParticipantId>();
                        }
                        writers.Add(id);
                    }
                }
                // manager
                if (manager == null && id.IsManager() && participant.Value.Writes > 0)
                {
                    manager = participant;
                }
            }
        }
 public Task Prepared(string resourceId, Guid transactionId, DateTime timestamp, ParticipantId resource, TransactionalStatus status)
 {
     return(GetManager(resourceId).Prepared(transactionId, timestamp, resource, status));
 }
 public Task Ping(string resourceId, Guid transactionId, DateTime timeStamp, ParticipantId resource)
 {
     return(GetManager(resourceId).Ping(transactionId, timeStamp, resource));
 }
 public Task Prepare(string resourceId, Guid transactionId, AccessCounter accessCount, DateTime timeStamp, ParticipantId transactionManager)
 {
     return(GetResource(resourceId).Prepare(transactionId, accessCount, timeStamp, transactionManager));
 }
Exemplo n.º 6
0
 public static bool IsPriorityManager(this ParticipantId participant)
 {
     return(participant.SupportsRoles(ParticipantId.Role.PriorityManager));
 }
Exemplo n.º 7
0
 public static bool IsResource(this ParticipantId participant)
 {
     return(participant.SupportsRoles(ParticipantId.Role.Resource));
 }
Exemplo n.º 8
0
 public static bool SupportsRoles(this ParticipantId participant, ParticipantId.Role role)
 {
     return((participant.SupportedRoles & role) != 0);
 }
Exemplo n.º 9
0
        private async Task <TransactionalStatus> CommitReadWriteTransaction(TransactionInfo transactionInfo, List <ParticipantId> writeResources)
        {
            ParticipantId tm = selectTMByBatchSize ? transactionInfo.TMCandidate : writeResources[0];
            Dictionary <ParticipantId, AccessCounter> participants = transactionInfo.Participants;

            Task <TransactionalStatus> tmPrepareAndCommitTask = null;

            foreach (var p in participants)
            {
                if (p.Key.Equals(tm))
                {
                    tmPrepareAndCommitTask = p.Key.Reference.AsReference <ITransactionManagerExtension>()
                                             .PrepareAndCommit(p.Key.Name, transactionInfo.TransactionId, p.Value, transactionInfo.TimeStamp, writeResources, participants.Count);
                }
                else
                {
                    // one-way prepare message
                    p.Key.Reference.AsReference <ITransactionalResourceExtension>()
                    .Prepare(p.Key.Name, transactionInfo.TransactionId, p.Value, transactionInfo.TimeStamp, tm)
                    .Ignore();
                }
            }

            try
            {
                // wait for the TM to commit the transaction
                TransactionalStatus status = await tmPrepareAndCommitTask;

                if (status != TransactionalStatus.Ok)
                {
                    if (logger.IsEnabled(LogLevel.Debug))
                    {
                        logger.Debug($"{stopwatch.Elapsed.TotalMilliseconds:f2} fail {transactionInfo.TransactionId} TM response status={status}");
                    }

                    // notify participants
                    if (status.DefinitelyAborted())
                    {
                        foreach (var p in writeResources)
                        {
                            if (!p.Equals(tm))
                            {
                                // one-way cancel message
                                p.Reference.AsReference <ITransactionalResourceExtension>()
                                .Cancel(p.Name, transactionInfo.TransactionId, transactionInfo.TimeStamp, status)
                                .Ignore();
                            }
                        }
                    }

                    return(status);
                }
            }
            catch (TimeoutException)
            {
                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug($"{stopwatch.Elapsed.TotalMilliseconds:f2} timeout {transactionInfo.TransactionId} TM response");
                }

                return(TransactionalStatus.TMResponseTimeout);
            }

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace($"{stopwatch.Elapsed.TotalMilliseconds:f2} finish {transactionInfo.TransactionId}");
            }

            return(TransactionalStatus.Ok);
        }