public Task MultiGrainAdd(ITransactionCommitterTestGrain committer, ITransactionCommitOperation <IRemoteCommitService> operation, List <ITransactionTestGrain> grains, int numberToAdd)
        {
            List <Task> tasks = new List <Task>();

            tasks.AddRange(grains.Select(g => g.Add(numberToAdd)));
            tasks.Add(committer.Commit(operation));
            return(Task.WhenAll(tasks));
        }
Example #2
0
        /// <inheritdoc/>
        public Task OnCommit(ITransactionCommitOperation <TService> operation)
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }
            if (detectReentrancy)
            {
                throw new LockRecursionException("cannot perform an update operation from within another operation");
            }

            var info = (TransactionInfo)TransactionContext.GetRequiredTransactionInfo <TransactionInfo>();

            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace($"StartWrite {info}");
            }

            if (info.IsReadOnly)
            {
                throw new OrleansReadOnlyViolatedException(info.Id);
            }

            info.Participants.TryGetValue(this.participantId, out var recordedaccesses);

            return(this.queue.RWLock.EnterLock <bool>(info.TransactionId, info.Priority, recordedaccesses, false,
                                                      new Task <bool>(() =>
            {
                // check if we expired while waiting
                if (!this.queue.RWLock.TryGetRecord(info.TransactionId, out TransactionRecord <OperationState> record))
                {
                    throw new OrleansCascadingAbortException(info.TransactionId.ToString());
                }

                // merge the current clock into the transaction time stamp
                record.Timestamp = this.queue.Clock.MergeUtcNow(info.TimeStamp);

                // link to the latest state
                if (record.State == null)
                {
                    this.queue.GetMostRecentState(out record.State, out record.SequenceNumber);
                }

                // if this is the first write, make a deep copy of the state
                if (!record.HasCopiedState)
                {
                    record.State = this.copier.DeepCopy(record.State);
                    record.SequenceNumber++;
                    record.HasCopiedState = true;
                }

                if (logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug($"update-lock write v{record.SequenceNumber} {record.TransactionId} {record.Timestamp:o}");
                }

                // record this write in the transaction info data structure
                info.RecordWrite(this.participantId, record.Timestamp);

                // perform the write
                try
                {
                    detectReentrancy = true;

                    record.State.Operation = operation;
                    return true;
                }
                finally
                {
                    if (logger.IsEnabled(LogLevel.Trace))
                    {
                        logger.Trace($"EndWrite {info} {record.TransactionId} {record.Timestamp}");
                    }

                    detectReentrancy = false;
                }
            }
                                                                      )));
        }
Example #3
0
 public Task Commit(ITransactionCommitOperation <IRemoteCommitService> operation)
 {
     return(this.committer.OnCommit(operation));
 }