Exemplo n.º 1
0
 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);
            }
        }
Exemplo n.º 5
0
        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;
        }
Exemplo n.º 8
0
 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);
     }
 }
Exemplo n.º 11
0
 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));
     }
 }
Exemplo n.º 12
0
 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;
 }
Exemplo n.º 13
0
        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);
        }
Exemplo n.º 14
0
 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);
 }
Exemplo n.º 17
0
        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);
        }
Exemplo n.º 18
0
        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;
        }
Exemplo n.º 19
0
 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);
 }
Exemplo n.º 20
0
        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;
        }
Exemplo n.º 21
0
 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);
     }
 }
Exemplo n.º 22
0
 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);
                }
            }
        }
Exemplo n.º 25
0
        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);
        }
Exemplo n.º 26
0
 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);
     }
 }
Exemplo n.º 28
0
 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);
     }
 }
Exemplo n.º 30
0
        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);
        }
Exemplo n.º 31
0
 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 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;
        }
        // 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);
     }
 }
 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;
 }