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; } }
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)); }
public static bool IsPriorityManager(this ParticipantId participant) { return(participant.SupportsRoles(ParticipantId.Role.PriorityManager)); }
public static bool IsResource(this ParticipantId participant) { return(participant.SupportsRoles(ParticipantId.Role.Resource)); }
public static bool SupportsRoles(this ParticipantId participant, ParticipantId.Role role) { return((participant.SupportedRoles & role) != 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); }