private void ApplyChangesFrom(EventQueueState srcPendingQueueState, Dictionary <IComparable, EventQueueState> srcPersistedQueueStates) { lock (this.SyncRoot) { Dictionary <IComparable, EventQueueState> dictionary = new Dictionary <IComparable, EventQueueState>(); foreach (KeyValuePair <IComparable, EventQueueState> pair in srcPersistedQueueStates) { if (pair.Value.Transactional) { if (this.persistedQueueStates.ContainsKey(pair.Key)) { EventQueueState state = this.persistedQueueStates[pair.Key]; if (!state.Dirty) { throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueBusyException, new object[] { pair.Key }), MessageQueueErrorCode.QueueNotAvailable); } } dictionary.Add(pair.Key, pair.Value); } } foreach (KeyValuePair <IComparable, EventQueueState> pair2 in dictionary) { this.persistedQueueStates[pair2.Key] = pair2.Value; } this.pendingQueueState.CopyFrom(srcPendingQueueState); } }
internal Object DequeueEvent(IComparable queueName) { if (queueName == null) { throw new ArgumentNullException("queueName"); } lock (SyncRoot) { if (this.rootQueuingService != null && !IsTransactionalQueue(queueName)) { return(this.rootQueuingService.DequeueEvent(queueName)); } EventQueueState queueState = GetEventQueueState(queueName); if (queueState.Messages.Count != 0) { return(queueState.Messages.Dequeue()); } object[] args = new object[] { System.Messaging.MessageQueueErrorCode.MessageNotFound, queueName }; string message = string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.EventQueueException, args); throw new QueueException(message, MessageQueueErrorCode.MessageNotFound); } }
internal bool SafeEnqueueEvent(IComparable queueName, Object item) { if (queueName == null) { throw new ArgumentNullException("queueName"); } lock (SyncRoot) { if (this.rootQueuingService != null && !IsTransactionalQueue(queueName)) { return(this.rootQueuingService.SafeEnqueueEvent(queueName, item)); } EventQueueState qState = GetQueue(queueName); if (!qState.Enabled) { throw new QueueException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueNotEnabled, queueName), MessageQueueErrorCode.QueueNotAvailable); } // note enqueue allowed irrespective of dirty flag since it is delivered through qState.Messages.Enqueue(item); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Enqueue item Queue ID {0} for {1}", queueName.GetHashCode(), queueName); // notify message arrived subscribers for (int i = 0; messageArrivalEventHandlers != null && i < messageArrivalEventHandlers.Count; ++i) { this.messageArrivalEventHandlers[i].OnItemSafeEnqueued(queueName, item); } NotifySynchronousSubscribers(queueName, qState, item); return(QueueAsynchronousEvent(queueName, qState)); } }
// returns a valid state only if transactional and entry exists private EventQueueState MarkQueueDirtyIfTransactional(IComparable queueName) { lock (SyncRoot) { Debug.Assert(this.rootQueuingService == null, "MarkQueueDirty should be done at root"); if (!this.persistedQueueStates.ContainsKey(queueName)) { return(null); } EventQueueState queueState = GetQueue(queueName); if (!queueState.Transactional) { return(null); } if (queueState.Dirty) { return(queueState); // already marked } queueState.Dirty = true; if (this.dirtyQueues == null) { this.dirtyQueues = new List <IComparable>(); } // add to the list of dirty queues this.dirtyQueues.Add(queueName); return(queueState); } }
internal object Peek(IComparable queueName) { object obj2; if (queueName == null) { throw new ArgumentNullException("queueName"); } lock (this.SyncRoot) { if ((this.rootQueuingService != null) && !this.IsTransactionalQueue(queueName)) { return(this.rootQueuingService.Peek(queueName)); } EventQueueState eventQueueState = this.GetEventQueueState(queueName); if (eventQueueState.Messages.Count != 0) { obj2 = eventQueueState.Messages.Peek(); } else { object[] args = new object[] { MessageQueueErrorCode.MessageNotFound, queueName }; throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.EventQueueException, args), MessageQueueErrorCode.MessageNotFound); } } return(obj2); }
// Created for ref. 20575 internal void PrePersist() { if (rootWorkflowExecutor.CurrentAtomicActivity != null) { // Create transactionalProperties from currentAtomicActivity TransactionalProperties transactionalProperties = this.rootWorkflowExecutor.CurrentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty) as TransactionalProperties; // Create backup snapshot of root queuing service's persistedQueuesStates // qService.persistedQueueStates is changed when LocalQueuingService.Complete is called later. persistedQueueStatesSnapshot = new Dictionary <IComparable, EventQueueState>(); foreach (KeyValuePair <IComparable, EventQueueState> kv in persistedQueueStates) { EventQueueState individualPersistedQueueStateValue = new EventQueueState(); individualPersistedQueueStateValue.CopyFrom(kv.Value); persistedQueueStatesSnapshot.Add(kv.Key, individualPersistedQueueStateValue); } // Create backup snapshot of root queuing service's pendingQueueState // qService.pendingQueueState is changed when LocalQueuingService.Complete is called later. pendingQueueStateSnapshot = new EventQueueState(); pendingQueueStateSnapshot.CopyFrom(pendingQueueState); // Reconcile differences between root and local queuing services. transactionalProperties.LocalQueuingService.Complete(true); } }
// Created for ref. 20575 internal void PostPersist(bool isPersistSuccessful) { // If persist is unsuccessful, we'll undo the changes done // because of the call to .Complete() in PrePresist if (!isPersistSuccessful) { Debug.Assert(rootWorkflowExecutor.CurrentAtomicActivity != null); Debug.Assert(pendingQueueStateSnapshot != null); Debug.Assert(persistedQueueStatesSnapshot != null); TransactionalProperties transactionalProperties = rootWorkflowExecutor.CurrentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty) as TransactionalProperties; Debug.Assert(transactionalProperties != null); // Restore queuing states and set root activity's dependency properties to the new values. pendingQueueState = pendingQueueStateSnapshot; persistedQueueStates = persistedQueueStatesSnapshot; rootWorkflowExecutor.RootActivity.SetValue(WorkflowQueuingService.RootPersistedQueueStatesProperty, persistedQueueStatesSnapshot); rootWorkflowExecutor.RootActivity.SetValue(WorkflowQueuingService.PendingMessagesProperty, pendingQueueStateSnapshot.Messages); // Also call Subscribe...() because the .Complete() call called Unsubscribe transactionalProperties.LocalQueuingService.SubscribeForRootMessageDelivery(); } // The backups are no longer necessary. // The next call to PrePresistQueuingServiceState() will do a re-backup. persistedQueueStatesSnapshot = null; pendingQueueStateSnapshot = null; }
private EventQueueState MarkQueueDirtyIfTransactional(IComparable queueName) { lock (this.SyncRoot) { if (!this.persistedQueueStates.ContainsKey(queueName)) { return(null); } EventQueueState queue = this.GetQueue(queueName); if (!queue.Transactional) { return(null); } if (!queue.Dirty) { queue.Dirty = true; if (this.dirtyQueues == null) { this.dirtyQueues = new List <IComparable>(); } this.dirtyQueues.Add(queueName); } return(queue); } }
public void DeleteWorkflowQueue(IComparable queueName) { if (queueName == null) { throw new ArgumentNullException("queueName"); } lock (SyncRoot) { // when we are deleting the queue from activity // message delivery should not happen. if (this.rootQueuingService != null && !IsTransactionalQueue(queueName)) { this.rootQueuingService.DeleteWorkflowQueue(queueName); return; } EventQueueState queueState = GetEventQueueState(queueName); Queue queue = queueState.Messages; Queue pendingQueue = this.pendingQueueState.Messages; while (queue.Count != 0) { pendingQueue.Enqueue(queue.Dequeue()); } WorkflowTrace.Runtime.TraceInformation("Queuing Service: Deleting Queue with ID {0} for {1}", queueName.GetHashCode(), queueName); this.persistedQueueStates.Remove(queueName); } }
private void ApplyChangesFrom(EventQueueState srcPendingQueueState, Dictionary<IComparable, EventQueueState> srcPersistedQueueStates) { lock (this.SyncRoot) { Dictionary<IComparable, EventQueueState> dictionary = new Dictionary<IComparable, EventQueueState>(); foreach (KeyValuePair<IComparable, EventQueueState> pair in srcPersistedQueueStates) { if (pair.Value.Transactional) { if (this.persistedQueueStates.ContainsKey(pair.Key)) { EventQueueState state = this.persistedQueueStates[pair.Key]; if (!state.Dirty) { throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueBusyException, new object[] { pair.Key }), MessageQueueErrorCode.QueueNotAvailable); } } dictionary.Add(pair.Key, pair.Value); } } foreach (KeyValuePair<IComparable, EventQueueState> pair2 in dictionary) { this.persistedQueueStates[pair2.Key] = pair2.Value; } this.pendingQueueState.CopyFrom(srcPendingQueueState); } }
internal bool SafeEnqueueEvent(IComparable queueName, object item) { if (queueName == null) { throw new ArgumentNullException("queueName"); } lock (this.SyncRoot) { if ((this.rootQueuingService != null) && !this.IsTransactionalQueue(queueName)) { return(this.rootQueuingService.SafeEnqueueEvent(queueName, item)); } EventQueueState queue = this.GetQueue(queueName); if (!queue.Enabled) { throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueNotEnabled, new object[] { queueName }), MessageQueueErrorCode.QueueNotAvailable); } queue.Messages.Enqueue(item); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Enqueue item Queue ID {0} for {1}", new object[] { queueName.GetHashCode(), queueName }); for (int i = 0; (this.messageArrivalEventHandlers != null) && (i < this.messageArrivalEventHandlers.Count); i++) { this.messageArrivalEventHandlers[i].OnItemSafeEnqueued(queueName, item); } this.NotifySynchronousSubscribers(queueName, queue, item); return(this.QueueAsynchronousEvent(queueName, queue)); } }
internal void CopyFrom(EventQueueState copyFromState) { this.deliveredMessages = new Queue(copyFromState.Messages); this.asynchronousListeners.AddRange(copyFromState.AsynchronousListeners.ToArray()); this.synchronousListeners.AddRange(copyFromState.SynchronousListeners.ToArray()); this.enabled = copyFromState.Enabled; this.transactional = copyFromState.Transactional; this.dirty = false; }
private EventQueueState GetEventQueueState(IComparable queueName) { EventQueueState queue = this.GetQueue(queueName); if (queue.Dirty) { throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueBusyException, new object[] { queueName }), MessageQueueErrorCode.QueueNotAvailable); } return(queue); }
internal WorkflowQueuingService(WorkflowQueuingService copyFromQueuingService) { this.syncRoot = new object(); this.pendingQueueState = new EventQueueState(); this.rootQueuingService = copyFromQueuingService; this.rootWorkflowExecutor = copyFromQueuingService.rootWorkflowExecutor; this.rootWorkflowExecutor.RootActivity.SetValue(PendingMessagesProperty, this.pendingQueueState.Messages); this.persistedQueueStates = new Dictionary <IComparable, EventQueueState>(); this.rootWorkflowExecutor.RootActivity.SetValue(LocalPersistedQueueStatesProperty, this.persistedQueueStates); this.SubscribeForRootMessageDelivery(); }
internal WorkflowQueuingService(WorkflowQueuingService copyFromQueuingService) { this.syncRoot = new object(); this.pendingQueueState = new EventQueueState(); this.rootQueuingService = copyFromQueuingService; this.rootWorkflowExecutor = copyFromQueuingService.rootWorkflowExecutor; this.rootWorkflowExecutor.RootActivity.SetValue(PendingMessagesProperty, this.pendingQueueState.Messages); this.persistedQueueStates = new Dictionary<IComparable, EventQueueState>(); this.rootWorkflowExecutor.RootActivity.SetValue(LocalPersistedQueueStatesProperty, this.persistedQueueStates); this.SubscribeForRootMessageDelivery(); }
private bool QueueAsynchronousEvent(IComparable queueName, EventQueueState qState) { if (qState.AsynchronousListeners.Count != 0 || IsNestedListenersExist(queueName)) { Queue q = GetQueue(pendingNotification).Messages; q.Enqueue(new KeyValuePair <IComparable, EventQueueState>(queueName, qState)); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Queued delayed message notification for '{0}'", queueName.ToString()); return(q.Count == 1); } return(false); }
private bool QueueAsynchronousEvent(IComparable queueName, EventQueueState qState) { if ((qState.AsynchronousListeners.Count == 0) && !this.IsNestedListenersExist(queueName)) { return(false); } Queue messages = this.GetQueue("*PendingNotifications").Messages; messages.Enqueue(new KeyValuePair <IComparable, EventQueueState>(queueName, qState)); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Queued delayed message notification for '{0}'", new object[] { queueName.ToString() }); return(messages.Count == 1); }
internal void CopyFrom(EventQueueState copyFromState) { this.deliveredMessages = new Queue(copyFromState.Messages); // don't copy Subscribers since this gets fixed // up at access time based on these tracking context ints this.asynchronousListeners.AddRange(copyFromState.AsynchronousListeners.ToArray()); this.synchronousListeners.AddRange(copyFromState.SynchronousListeners.ToArray()); this.enabled = copyFromState.Enabled; this.transactional = copyFromState.Transactional; this.dirty = false; }
private bool IsNestedListenersExist(IComparable queueName) { for (int i = 0; (this.messageArrivalEventHandlers != null) && (i < this.messageArrivalEventHandlers.Count); i++) { WorkflowQueuingService service = this.messageArrivalEventHandlers[i]; EventQueueState state = null; if (service.persistedQueueStates.TryGetValue(queueName, out state) && (state.AsynchronousListeners.Count != 0)) { return(true); } } return(false); }
private void OnItemSafeEnqueued(IComparable queueName, object item) { if (this.persistedQueueStates.ContainsKey(queueName)) { EventQueueState queue = this.GetQueue(queueName); if (!queue.Enabled) { object[] args = new object[] { MessageQueueErrorCode.QueueNotFound, queueName }; throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.EventQueueException, args), MessageQueueErrorCode.QueueNotAvailable); } queue.Messages.Enqueue(item); this.NotifySynchronousSubscribers(queueName, queue, item); } }
internal void PostPersist(bool isPersistSuccessful) { if (!isPersistSuccessful) { TransactionalProperties properties = this.rootWorkflowExecutor.CurrentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty) as TransactionalProperties; this.pendingQueueState = this.pendingQueueStateSnapshot; this.persistedQueueStates = this.persistedQueueStatesSnapshot; this.rootWorkflowExecutor.RootActivity.SetValue(RootPersistedQueueStatesProperty, this.persistedQueueStatesSnapshot); this.rootWorkflowExecutor.RootActivity.SetValue(PendingMessagesProperty, this.pendingQueueStateSnapshot.Messages); properties.LocalQueuingService.SubscribeForRootMessageDelivery(); } this.persistedQueueStatesSnapshot = null; this.pendingQueueStateSnapshot = null; }
bool IsNestedListenersExist(IComparable queueName) { for (int i = 0; messageArrivalEventHandlers != null && i < messageArrivalEventHandlers.Count; ++i) { WorkflowQueuingService qService = messageArrivalEventHandlers[i]; EventQueueState queueState = null; if (qService.persistedQueueStates.TryGetValue(queueName, out queueState) && queueState.AsynchronousListeners.Count != 0) { return(true); } } return(false); }
private void NotifySynchronousSubscribers(IComparable queueName, EventQueueState qState, Object eventInstance) { QueueEventArgs args = new QueueEventArgs(queueName); for (int i = 0; i < qState.SynchronousListeners.Count; ++i) { if (qState.SynchronousListeners[i].HandlerDelegate != null) { qState.SynchronousListeners[i].HandlerDelegate(new WorkflowQueue(this, queueName), args); } else { qState.SynchronousListeners[i].EventListener.OnEvent(new WorkflowQueue(this, queueName), args); } } }
private void NewQueue(IComparable queueID, bool enabled, bool transactional) { WorkflowTrace.Runtime.TraceInformation("Queuing Service: Creating new Queue with ID {0} for {1}", new object[] { queueID.GetHashCode(), queueID }); if (this.persistedQueueStates.ContainsKey(queueID)) { object[] args = new object[] { MessageQueueErrorCode.QueueExists, queueID }; throw new QueueException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.EventQueueException, args), MessageQueueErrorCode.QueueExists); } EventQueueState state = new EventQueueState { Enabled = enabled, queueName = queueID, Transactional = transactional }; this.persistedQueueStates.Add(queueID, state); }
internal void NotifyAsynchronousSubscribers(IComparable queueName, EventQueueState qState, int numberOfNotification) { for (int i = 0; i < numberOfNotification; i++) { QueueEventArgs e = new QueueEventArgs(queueName); lock (this.SyncRoot) { foreach (ActivityExecutorDelegateInfo <QueueEventArgs> info in qState.AsynchronousListeners) { Activity contextActivityForId = this.rootWorkflowExecutor.GetContextActivityForId(info.ContextId); info.InvokeDelegate(contextActivityForId, e, false); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Notifying async subscriber on queue:'{0}' activity:{1}", new object[] { queueName.ToString(), info.ActivityQualifiedName }); } } } }
private void OnItemSafeEnqueued(IComparable queueName, object item) { if (this.persistedQueueStates.ContainsKey(queueName)) { // make the message visible to inner queueing service EventQueueState qState = GetQueue(queueName); if (!qState.Enabled) { object[] msgArgs = new object[] { System.Messaging.MessageQueueErrorCode.QueueNotFound, queueName }; string message = string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.EventQueueException, msgArgs); throw new QueueException(message, MessageQueueErrorCode.QueueNotAvailable); } qState.Messages.Enqueue(item); NotifySynchronousSubscribers(queueName, qState, item); } }
internal void PrePersist() { if (this.rootWorkflowExecutor.CurrentAtomicActivity != null) { TransactionalProperties properties = this.rootWorkflowExecutor.CurrentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty) as TransactionalProperties; this.persistedQueueStatesSnapshot = new Dictionary <IComparable, EventQueueState>(); foreach (KeyValuePair <IComparable, EventQueueState> pair in this.persistedQueueStates) { EventQueueState state = new EventQueueState(); state.CopyFrom(pair.Value); this.persistedQueueStatesSnapshot.Add(pair.Key, state); } this.pendingQueueStateSnapshot = new EventQueueState(); this.pendingQueueStateSnapshot.CopyFrom(this.pendingQueueState); properties.LocalQueuingService.Complete(true); } }
internal WorkflowQueuingService(IWorkflowCoreRuntime rootWorkflowExecutor) { this.syncRoot = new object(); this.pendingQueueState = new EventQueueState(); this.rootWorkflowExecutor = rootWorkflowExecutor; this.rootWorkflowExecutor.RootActivity.SetValue(PendingMessagesProperty, this.pendingQueueState.Messages); this.persistedQueueStates = (Dictionary<IComparable, EventQueueState>) this.rootWorkflowExecutor.RootActivity.GetValue(RootPersistedQueueStatesProperty); if (this.persistedQueueStates == null) { this.persistedQueueStates = new Dictionary<IComparable, EventQueueState>(); this.rootWorkflowExecutor.RootActivity.SetValue(RootPersistedQueueStatesProperty, this.persistedQueueStates); } if (!this.Exists("*PendingNotifications")) { this.CreateWorkflowQueue("*PendingNotifications", false); } }
private bool IsTransactionalQueue(IComparable queueName) { if (this.persistedQueueStates.ContainsKey(queueName)) { return(true); } EventQueueState copyFromState = this.rootQueuingService.MarkQueueDirtyIfTransactional(queueName); if (copyFromState != null) { EventQueueState state2 = new EventQueueState(); state2.CopyFrom(copyFromState); this.persistedQueueStates.Add(queueName, state2); return(true); } return(false); }
internal WorkflowQueuingService(IWorkflowCoreRuntime rootWorkflowExecutor) { this.syncRoot = new object(); this.pendingQueueState = new EventQueueState(); this.rootWorkflowExecutor = rootWorkflowExecutor; this.rootWorkflowExecutor.RootActivity.SetValue(PendingMessagesProperty, this.pendingQueueState.Messages); this.persistedQueueStates = (Dictionary <IComparable, EventQueueState>) this.rootWorkflowExecutor.RootActivity.GetValue(RootPersistedQueueStatesProperty); if (this.persistedQueueStates == null) { this.persistedQueueStates = new Dictionary <IComparable, EventQueueState>(); this.rootWorkflowExecutor.RootActivity.SetValue(RootPersistedQueueStatesProperty, this.persistedQueueStates); } if (!this.Exists("*PendingNotifications")) { this.CreateWorkflowQueue("*PendingNotifications", false); } }
internal void NotifyAsynchronousSubscribers(IComparable queueName, EventQueueState qState, int numberOfNotification) { for (int i = 0; i < numberOfNotification; ++i) { QueueEventArgs args = new QueueEventArgs(queueName); lock (SyncRoot) { foreach (ActivityExecutorDelegateInfo <QueueEventArgs> subscriber in qState.AsynchronousListeners) { Activity contextActivity = rootWorkflowExecutor.GetContextActivityForId(subscriber.ContextId); Debug.Assert(contextActivity != null); subscriber.InvokeDelegate(contextActivity, args, false); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Notifying async subscriber on queue:'{0}' activity:{1}", queueName.ToString(), subscriber.ActivityQualifiedName); } } } }
private void RemoveMessageArrivedEventHandler(WorkflowQueuingService handler) { lock (SyncRoot) { if (this.messageArrivalEventHandlers != null) { this.messageArrivalEventHandlers.Remove(handler); } if (this.dirtyQueues != null) { foreach (IComparable queueName in this.dirtyQueues) { EventQueueState qState = GetQueue(queueName); qState.Dirty = false; } } } }
private void ApplyChangesFrom(EventQueueState srcPendingQueueState, Dictionary <IComparable, EventQueueState> srcPersistedQueueStates) { lock (SyncRoot) { Dictionary <IComparable, EventQueueState> modifiedItems = new Dictionary <IComparable, EventQueueState>(); foreach (KeyValuePair <IComparable, EventQueueState> mergeItem in srcPersistedQueueStates) { Debug.Assert(mergeItem.Value.Transactional, "Queue inside a transactional context is not transactional!"); if (mergeItem.Value.Transactional) { if (this.persistedQueueStates.ContainsKey(mergeItem.Key)) { EventQueueState oldvalue = this.persistedQueueStates[mergeItem.Key]; if (!oldvalue.Dirty) { // we could get here when there // are conflicting create Qs string message = string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueBusyException, new object[] { mergeItem.Key }); throw new QueueException(message, MessageQueueErrorCode.QueueNotAvailable); } } modifiedItems.Add(mergeItem.Key, mergeItem.Value); } } // no conflicts detected now make the updates visible foreach (KeyValuePair <IComparable, EventQueueState> modifiedItem in modifiedItems) { // shared queue in the root, swap out to new value // or add new item this.persistedQueueStates[modifiedItem.Key] = modifiedItem.Value; } this.pendingQueueState.CopyFrom(srcPendingQueueState); } }
private bool IsTransactionalQueue(IComparable queueName) { if (this.persistedQueueStates.ContainsKey(queueName)) { return true; } EventQueueState copyFromState = this.rootQueuingService.MarkQueueDirtyIfTransactional(queueName); if (copyFromState != null) { EventQueueState state2 = new EventQueueState(); state2.CopyFrom(copyFromState); this.persistedQueueStates.Add(queueName, state2); return true; } return false; }
// Created for ref. 20575 internal void PrePersist() { if (rootWorkflowExecutor.CurrentAtomicActivity != null) { // Create transactionalProperties from currentAtomicActivity TransactionalProperties transactionalProperties = this.rootWorkflowExecutor.CurrentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty) as TransactionalProperties; // Create backup snapshot of root queuing service's persistedQueuesStates // qService.persistedQueueStates is changed when LocalQueuingService.Complete is called later. persistedQueueStatesSnapshot = new Dictionary<IComparable, EventQueueState>(); foreach (KeyValuePair<IComparable, EventQueueState> kv in persistedQueueStates) { EventQueueState individualPersistedQueueStateValue = new EventQueueState(); individualPersistedQueueStateValue.CopyFrom(kv.Value); persistedQueueStatesSnapshot.Add(kv.Key, individualPersistedQueueStateValue); } // Create backup snapshot of root queuing service's pendingQueueState // qService.pendingQueueState is changed when LocalQueuingService.Complete is called later. pendingQueueStateSnapshot = new EventQueueState(); pendingQueueStateSnapshot.CopyFrom(pendingQueueState); // Reconcile differences between root and local queuing services. transactionalProperties.LocalQueuingService.Complete(true); } }
private void NotifySynchronousSubscribers(IComparable queueName, EventQueueState qState, Object eventInstance) { QueueEventArgs args = new QueueEventArgs(queueName); for (int i = 0; i < qState.SynchronousListeners.Count; ++i) { if (qState.SynchronousListeners[i].HandlerDelegate != null) qState.SynchronousListeners[i].HandlerDelegate(new WorkflowQueue(this, queueName), args); else qState.SynchronousListeners[i].EventListener.OnEvent(new WorkflowQueue(this, queueName), args); } }
private bool IsTransactionalQueue(IComparable queueName) { // check inner service for existense if (!this.persistedQueueStates.ContainsKey(queueName)) { EventQueueState queueState = this.rootQueuingService.MarkQueueDirtyIfTransactional(queueName); if (queueState != null) { // if transactional proceed to the inner queue service // for this operation after adding the state EventQueueState snapshotState = new EventQueueState(); snapshotState.CopyFrom(queueState); this.persistedQueueStates.Add(queueName, snapshotState); return true; } return false; } return true; // if entry exits, it must be transactional }
private void ApplyChangesFrom(EventQueueState srcPendingQueueState, Dictionary<IComparable, EventQueueState> srcPersistedQueueStates) { lock (SyncRoot) { Dictionary<IComparable, EventQueueState> modifiedItems = new Dictionary<IComparable, EventQueueState>(); foreach (KeyValuePair<IComparable, EventQueueState> mergeItem in srcPersistedQueueStates) { Debug.Assert(mergeItem.Value.Transactional, "Queue inside a transactional context is not transactional!"); if (mergeItem.Value.Transactional) { if (this.persistedQueueStates.ContainsKey(mergeItem.Key)) { EventQueueState oldvalue = this.persistedQueueStates[mergeItem.Key]; if (!oldvalue.Dirty) { // we could get here when there // are conflicting create Qs string message = string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueBusyException, new object[] { mergeItem.Key }); throw new QueueException(message, MessageQueueErrorCode.QueueNotAvailable); } } modifiedItems.Add(mergeItem.Key, mergeItem.Value); } } // no conflicts detected now make the updates visible foreach (KeyValuePair<IComparable, EventQueueState> modifiedItem in modifiedItems) { // shared queue in the root, swap out to new value // or add new item this.persistedQueueStates[modifiedItem.Key] = modifiedItem.Value; } this.pendingQueueState.CopyFrom(srcPendingQueueState); } }
// message arrival async notification private void NotifyExternalSubscribers(IComparable queueName, EventQueueState qState, Object eventInstance) { NotifySynchronousSubscribers(queueName, qState, eventInstance); NotifyAsynchronousSubscribers(queueName, qState, 1); }
internal void NotifyAsynchronousSubscribers(IComparable queueName, EventQueueState qState, int numberOfNotification) { for (int i = 0; i < numberOfNotification; ++i) { QueueEventArgs args = new QueueEventArgs(queueName); lock (SyncRoot) { foreach (ActivityExecutorDelegateInfo<QueueEventArgs> subscriber in qState.AsynchronousListeners) { Activity contextActivity = rootWorkflowExecutor.GetContextActivityForId(subscriber.ContextId); Debug.Assert(contextActivity != null); subscriber.InvokeDelegate(contextActivity, args, false); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Notifying async subscriber on queue:'{0}' activity:{1}", queueName.ToString(), subscriber.ActivityQualifiedName); } } } }
private void NewQueue(IComparable queueID, bool enabled, bool transactional) { WorkflowTrace.Runtime.TraceInformation("Queuing Service: Creating new Queue with ID {0} for {1}", queueID.GetHashCode(), queueID); if (this.persistedQueueStates.ContainsKey(queueID)) { object[] args = new object[] { System.Messaging.MessageQueueErrorCode.QueueExists, queueID }; string message = string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.EventQueueException, args); throw new QueueException(message, MessageQueueErrorCode.QueueExists); } EventQueueState queueState = new EventQueueState(); queueState.Enabled = enabled; queueState.queueName = queueID; queueState.Transactional = transactional; this.persistedQueueStates.Add(queueID, queueState); }
private bool QueueAsynchronousEvent(IComparable queueName, EventQueueState qState) { if (qState.AsynchronousListeners.Count != 0 || IsNestedListenersExist(queueName)) { Queue q = GetQueue(pendingNotification).Messages; q.Enqueue(new KeyValuePair<IComparable, EventQueueState>(queueName, qState)); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Queued delayed message notification for '{0}'", queueName.ToString()); return q.Count == 1; } return false; }
internal void NotifyAsynchronousSubscribers(IComparable queueName, EventQueueState qState, int numberOfNotification) { for (int i = 0; i < numberOfNotification; i++) { QueueEventArgs e = new QueueEventArgs(queueName); lock (this.SyncRoot) { foreach (ActivityExecutorDelegateInfo<QueueEventArgs> info in qState.AsynchronousListeners) { Activity contextActivityForId = this.rootWorkflowExecutor.GetContextActivityForId(info.ContextId); info.InvokeDelegate(contextActivityForId, e, false); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Notifying async subscriber on queue:'{0}' activity:{1}", new object[] { queueName.ToString(), info.ActivityQualifiedName }); } } } }
private bool QueueAsynchronousEvent(IComparable queueName, EventQueueState qState) { if ((qState.AsynchronousListeners.Count == 0) && !this.IsNestedListenersExist(queueName)) { return false; } Queue messages = this.GetQueue("*PendingNotifications").Messages; messages.Enqueue(new KeyValuePair<IComparable, EventQueueState>(queueName, qState)); WorkflowTrace.Runtime.TraceInformation("Queuing Service: Queued delayed message notification for '{0}'", new object[] { queueName.ToString() }); return (messages.Count == 1); }
internal void PrePersist() { if (this.rootWorkflowExecutor.CurrentAtomicActivity != null) { TransactionalProperties properties = this.rootWorkflowExecutor.CurrentAtomicActivity.GetValue(WorkflowExecutor.TransactionalPropertiesProperty) as TransactionalProperties; this.persistedQueueStatesSnapshot = new Dictionary<IComparable, EventQueueState>(); foreach (KeyValuePair<IComparable, EventQueueState> pair in this.persistedQueueStates) { EventQueueState state = new EventQueueState(); state.CopyFrom(pair.Value); this.persistedQueueStatesSnapshot.Add(pair.Key, state); } this.pendingQueueStateSnapshot = new EventQueueState(); this.pendingQueueStateSnapshot.CopyFrom(this.pendingQueueState); properties.LocalQueuingService.Complete(true); } }