/// <summary> /// Drain all the dequeuers. /// Would be called during ChangeRole (to S, None), Abort, Close. /// </summary> /// <param name="cause">The DrainCause</param> private void DrainDequeuers(DequeuerState cause) { TaskCompletionSource <ConditionalValue <IListElement <T> > > tcs; Exception exc = null; switch (cause) { case DequeuerState.Aborting: case DequeuerState.Closing: exc = new FabricObjectClosedException(string.Format("Dequeue was canceled as the queue is {0}. Please dispose the current transaction and retry the operation with a new transaction.", cause)); break; case DequeuerState.ChangeRoleFromPrimary: exc = new FabricNotPrimaryException("Dequeue was canceled as the role is no longer primary. Please dispose the current transaction and retry the operation with a new transaction."); break; default: TestableAssertHelper.FailInvalidData( this.traceType, "DataStore.DrainDequeuers", "DequeueScheduler.DrainDequeuers : Invalid DrainQueue cause : {0}", cause); break; // unreachable } lock (this.updateLatch) { this.dequeuersState = cause; } while (this.dequeuerQueue.TryDequeue(out tcs)) { tcs.TrySetException(exc); } }
public void ChangeRole(ReplicaRole currentRole, ReplicaRole newRole) { // noop the call for a NonBlocking Queue if (this.queueMode == RCQMode.Blocking) { if (currentRole == ReplicaRole.Primary) { this.DrainDequeuers(DequeuerState.ChangeRoleFromPrimary); } if (newRole == ReplicaRole.Primary) { this.AssertNoDequeuer(); this.dequeuersState = DequeuerState.OnPrimary; } } }
public DataStore(List <IListElement <T> > listElements, RCQMode rcqMode, string traceType) { this.queueMode = rcqMode; this.traceType = traceType; this.dequeuerQueue = new ConcurrentQueue <TaskCompletionSource <ConditionalValue <IListElement <T> > > >(); this.dequeuersState = DequeuerState.None; this.LinkedCount = 0; this.updateLatch = new object(); this.ListElements = new ConcurrentDictionary <long, ListElement>(); this.head = null; this.tail = null; // descending order listElements.Sort((a, b) => b.Id.CompareTo(a.Id)); foreach (var listElement in listElements) { this.AddListElement(listElement); this.AssertUnlinked(listElement); this.LinkHeadUnsafe(listElement); } }