protected void OnNewWorkerAvailable(WorkerProcess worker) { lock (this.workers) { worker.Queue = this; workers.Add(worker); // offload draining the IO queues to this new worker on a different thread ActionItem.Schedule(dispatchToNewWorkerCallback, worker); } }
internal virtual void Unregister(WorkerProcess worker) { Debug.Print("MessageQueue.Unregister() worker: " + worker.ProcessId); lock (registry) { Fx.Assert(object.Equals(this, worker.Queue), "MessageQueue.Unregister() cannot unregister a worker registered with a queue different than this."); workers.Remove(worker); Debug.Print("MessageQueue.Unregister() left with workers: " + workers.Count); if (workers.Count == 0) { OnUnregisterLastWorker(); } } }
internal static ListenerExceptionStatus Register(BaseUriWithWildcard path, WorkerProcess worker) { MessageQueue queue = null; lock (registry) { if (registry.TryGetValue(path, out queue)) { if (!queue.CanShare) { return(ListenerExceptionStatus.ConflictingRegistration); } } else { queue = new MessageQueue(); ListenerExceptionStatus status = ListenerExceptionStatus.FailedToListen; try { status = queue.Register(path); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } if (DiagnosticUtility.ShouldTraceError) { ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.RoutingTableCannotListen, SR.GetString(SR.TraceCodeRoutingTableCannotListen), new StringTraceRecord("Path", path.ToString()), null, exception); } } if (status != ListenerExceptionStatus.Success) { // not setting the worker.queue is not a problem, since we can't use this WorkerProcess return(status); } registry.Add(path, queue); } } queue.OnNewWorkerAvailable(worker); return(ListenerExceptionStatus.Success); }
void EnqueueWorkerAndDispatch(WorkerProcess worker, bool canDispatchOnThisThread) { lock (SessionLock) { sessionWorkers.Enqueue(worker); } if (canDispatchOnThisThread) { DispatchSession(); } else { ActionItem.Schedule(dispatchSessionCallback, this); } }
void DispatchSession() { for (;;) { ListenerSessionConnection session = null; lock (SessionLock) { if (sessionMessages.Count > 0) { WorkerProcess worker = null; while (sessionWorkers.Count > 0) { worker = sessionWorkers.Dequeue(); if (worker.IsRegistered) { break; } worker = null; } if (worker == null) { // There is no more active worker. So break the loop. break; } // For better performance, we may want to check whether the message has been timed out in the future. session = sessionMessages.Dequeue(); session.WorkerProcess = worker; } } if (session == null) { // There is mo more message left. So break the loop. break; } StartDispatchSession(session); } }
static void DispatchToNewWorkerCallback(object state) { WorkerProcess worker = state as WorkerProcess; worker.Queue.EnqueueWorkerAndDispatch(worker, true); }
internal static ListenerExceptionStatus Register(int listenerChannelId, Guid token, WorkerProcess worker) { Debug.Print("ActivatedMessageQueue.Register() listenerChannelId: " + listenerChannelId + " token: " + token + " worker: " + worker.ProcessId); ActivatedMessageQueue thisPtr = null; lock (listenerChannelIds) { thisPtr = Find(listenerChannelId); if (thisPtr == null) { // this is an error. return ListenerExceptionStatus.InvalidArgument; } if (!token.Equals(thisPtr.listenerChannelContext.Token)) { return ListenerExceptionStatus.InvalidArgument; } } thisPtr.OnListenerChannelConnected(); thisPtr.OnNewWorkerAvailable(worker); return ListenerExceptionStatus.Success; }
internal static ListenerExceptionStatus Register(BaseUriWithWildcard path, WorkerProcess worker) { MessageQueue queue = null; lock (registry) { if (registry.TryGetValue(path, out queue)) { if (!queue.CanShare) { return ListenerExceptionStatus.ConflictingRegistration; } } else { queue = new MessageQueue(); ListenerExceptionStatus status = ListenerExceptionStatus.FailedToListen; try { status = queue.Register(path); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } if (DiagnosticUtility.ShouldTraceError) { ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.RoutingTableCannotListen, SR.GetString(SR.TraceCodeRoutingTableCannotListen), new StringTraceRecord("Path", path.ToString()), null, exception); } } if (status != ListenerExceptionStatus.Success) { // not setting the worker.queue is not a problem, since we can't use this WorkerProcess return status; } registry.Add(path, queue); } } queue.OnNewWorkerAvailable(worker); return ListenerExceptionStatus.Success; }
internal static ListenerExceptionStatus Register(int listenerChannelId, Guid token, WorkerProcess worker) { Debug.Print("ActivatedMessageQueue.Register() listenerChannelId: " + listenerChannelId + " token: " + token + " worker: " + worker.ProcessId); ActivatedMessageQueue thisPtr = null; lock (listenerChannelIds) { thisPtr = Find(listenerChannelId); if (thisPtr == null) { // this is an error. return(ListenerExceptionStatus.InvalidArgument); } if (!token.Equals(thisPtr.listenerChannelContext.Token)) { return(ListenerExceptionStatus.InvalidArgument); } } thisPtr.OnListenerChannelConnected(); thisPtr.OnNewWorkerAvailable(worker); return(ListenerExceptionStatus.Success); }