private NotificationManager.AsyncEvent GetNextEvent() { IAsyncCommand asyncCommand = this.command; NotificationManager.AsyncEvent result; lock (this.eventQueue) { if (this.eventQueue.Count > 0) { NotificationManager.AsyncEvent asyncEvent = this.eventQueue.Peek(); if ((asyncCommand != null && !asyncCommand.ProcessingEventsEnabled) || (asyncEvent.Command != null && !asyncEvent.Command.ProcessingEventsEnabled)) { result = null; } else { result = this.eventQueue.Dequeue(); } } else { result = null; } } return(result); }
private bool EnqueueEvent(NotificationManager.AsyncEvent evt) { bool result; lock (this.eventQueue) { if (this.disposed && evt.Type != NotificationManager.AsyncEventType.Release) { result = false; } else if (evt.Type == NotificationManager.AsyncEventType.Acquire && (!this.subscriptionCanBeTaken || ExDateTime.UtcNow > this.policyExpirationTime)) { result = false; } else { if (evt.Type != NotificationManager.AsyncEventType.Timeout && evt.Type != NotificationManager.AsyncEventType.Acquire && evt.Type != NotificationManager.AsyncEventType.Release) { this.subscriptionCanBeTaken = false; this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Locked); } this.eventQueue.Enqueue(evt); AirSyncDiagnostics.TraceDebug <string, string>(ExTraceGlobals.ThreadingTracer, this, "Enqueue event for {0}. processingEnabled:{1}", this.uniqueId, (this.command == null) ? "<null command>" : this.command.ProcessingEventsEnabled.ToString()); if (this.command == null || this.command.ProcessingEventsEnabled) { this.ProcessQueuedEvents(null); } result = true; } } return(result); }
private void ProcessAccountTerminated(NotificationManager.AsyncEvent evt) { this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.AccountTerminated); if (this.command == null) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Account terminated after XSO event callback for {0}, but command is not available. Calling Kill", this.uniqueId); this.Kill(); return; } this.command.HandleAccountTerminated(evt); AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Account terminated after XSO event callback for {0}. calling Command.HandleAccountTerminated", this.uniqueId); }
private void ProcessXsoEventAvailable(NotificationManager.AsyncEvent evt, IBudget budget) { Interlocked.Increment(ref this.totalXsoEvents); this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.XsoEvent, new EventType?(evt.Event.EventType), new EventObjectType?(evt.Event.ObjectType), null); if (this.command == null) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "XSO event available for {0}, but command is not available. Calling Kill", this.uniqueId); this.Kill(); return; } budget.CheckOverBudget(); this.command.Consume(evt.Event); AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "XSO event available for {0}. calling Command.Consume", this.uniqueId); }
private void ProcessAcquire(NotificationManager.AsyncEvent evt) { Interlocked.Increment(ref this.totalAcquires); this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Acquired); if (this.command != null) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Release notificationManager for {0}", this.uniqueId); this.command.ReleaseNotificationManager(true); } this.command = evt.Command; AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Acquiring notification manager for {0}", this.uniqueId); if (this.RequestedWaitTime > 0U && this.command != null) { this.InternalStartTimer(this.command.Context.RequestTime, this.RequestedWaitTime); } }
private void ProcessRelease(NotificationManager.AsyncEvent evt) { Interlocked.Increment(ref this.totalReleases); this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Released); evt.Command.ReleaseNotificationManager(false); if (this.command == evt.Command) { this.command = null; if (this.RequestedWaitTime > 0U && !this.disposed) { this.InternalStartTimer(ExDateTime.UtcNow, 120U); return; } this.Kill(); AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Release & killing {0}", this.uniqueId); } }
private void ProcessXsoException(NotificationManager.AsyncEvent evt) { Interlocked.Increment(ref this.totalXsoExceptions); this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.XsoException, null, null, evt.Exception); if (this.command == null) { if (!this.InternalHandleException(evt.Exception)) { throw evt.Exception; } } else { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "XSO exception event available for {0}. calling Command.HandleException", this.uniqueId); this.command.HandleException(evt.Exception); } }
private void Kill() { Interlocked.Increment(ref this.totalKills); if (this.disposed) { return; } AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Processing Kill event for {0}", this.uniqueId); lock (NotificationManager.notificationManagerCache) { NotificationManager notificationManager; if (NotificationManager.notificationManagerCache.TryGetValue(this.uniqueId, out notificationManager) && notificationManager == this) { notificationManager.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Removed); NotificationManager.notificationManagerCache.Remove(this.uniqueId); AirSyncCounters.NumberOfNotificationManagerInCache.RawValue = (long)NotificationManager.notificationManagerCache.Count; } } NotificationManager notificationManager2 = null; if (NotificationManager.removedInstances.TryGetValue(this.uniqueId, out notificationManager2) && notificationManager2 == this) { NotificationManager.removedInstances.TryRemove(this.uniqueId, out notificationManager2); } this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Killed); lock (this.eventQueue) { GC.SuppressFinalize(this); this.subscriptionCanBeTaken = false; this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Locked); if (this.disposeTracker != null) { this.disposeTracker.Dispose(); this.disposeTracker = null; } if (this.timer != null) { this.timer.Dispose(); this.timer = null; } if (this.eventSubscriptions.Count > 0) { foreach (EventSubscription eventSubscription in this.eventSubscriptions) { eventSubscription.Dispose(); } this.eventSubscriptions.Clear(); } List <NotificationManager.AsyncEvent> list = new List <NotificationManager.AsyncEvent>(this.eventSubscriptions.Count + 1); if (this.command != null) { NotificationManager.AsyncEvent item = new NotificationManager.AsyncEvent(NotificationManager.AsyncEventType.Release, this.command); list.Add(item); } foreach (NotificationManager.AsyncEvent asyncEvent in this.eventQueue) { if (asyncEvent.Type == NotificationManager.AsyncEventType.Acquire) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Changing Acquire into a Release for {0}", this.uniqueId); asyncEvent.Type = NotificationManager.AsyncEventType.Release; list.Add(asyncEvent); } else if (asyncEvent.Type == NotificationManager.AsyncEventType.Release) { list.Add(asyncEvent); } else { AirSyncDiagnostics.TraceDebug <NotificationManager.AsyncEventType, string>(ExTraceGlobals.ThreadingTracer, this, "Ignoring event {0} after a Kill for {1}", asyncEvent.Type, this.uniqueId); } } this.eventQueue.Clear(); foreach (NotificationManager.AsyncEvent item2 in list) { this.eventQueue.Enqueue(item2); } this.disposed = true; } }
public void ReleaseCommand(IAsyncCommand command) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, this, "Release Command for {0}", this.uniqueId); NotificationManager.AsyncEvent evt = new NotificationManager.AsyncEvent(NotificationManager.AsyncEventType.Release, command); this.EnqueueEvent(evt); }
public void ProcessQueuedEvents(IAsyncCommand callingCommand) { NotificationManager.AsyncEvent asyncEvent = null; if (this.currentlyExecuting) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.RequestsTracer, this, "ProcessQueuedEvents.UniqueId:{0}. Already processing event. Exiting.", this.uniqueId); return; } lock (this.eventQueue) { if (this.currentlyExecuting) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.RequestsTracer, this, "ProcessQueuedEvents.UniqueId:{0}. Already processing event. Exiting.", this.uniqueId); return; } this.currentlyExecuting = true; } IBudget budget = null; try { this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.RunStart); budget = StandardBudget.Acquire(this.budgetKey); lock (this.eventQueue) { if (callingCommand != null) { callingCommand.ProcessingEventsEnabled = true; } AirSyncDiagnostics.TraceDebug <string, string, int>(ExTraceGlobals.RequestsTracer, this, "ProcessQueuedEvents.UniqueId:{0}, ProcessingEnabled: {1}, eventQueue count:{2}.", this.uniqueId, (callingCommand == null) ? "<null command>" : "true", this.eventQueue.Count); asyncEvent = this.GetNextEvent(); } IAsyncCommand cmd = null; bool flag3 = asyncEvent != null; while (flag3) { try { cmd = this.StartCommandContext(); AirSyncDiagnostics.TraceDebug <NotificationManager.AsyncEventType, string, bool>(ExTraceGlobals.ThreadingTracer, this, "Processing event {0} for {1}. Command is null? {2}", asyncEvent.Type, this.uniqueId, this.command == null); switch (asyncEvent.Type) { case NotificationManager.AsyncEventType.XsoEventAvailable: this.ProcessXsoEventAvailable(asyncEvent, budget); break; case NotificationManager.AsyncEventType.XsoException: this.ProcessXsoException(asyncEvent); break; case NotificationManager.AsyncEventType.Timeout: this.ProcessTimeout(budget); break; case NotificationManager.AsyncEventType.Acquire: this.ProcessAcquire(asyncEvent); break; case NotificationManager.AsyncEventType.Release: this.ProcessRelease(asyncEvent); break; case NotificationManager.AsyncEventType.Kill: this.Kill(); break; case NotificationManager.AsyncEventType.AccountTerminated: this.ProcessAccountTerminated(asyncEvent); break; } } catch (Exception ex) { AirSyncDiagnostics.TraceDebug <string, string>(ExTraceGlobals.ThreadingTracer, this, "Exception in processQueuedEvents for {0}. Exception:{1}", this.uniqueId, ex.ToString()); if (!this.InternalHandleException(ex)) { throw; } } finally { this.EndCommandContext(cmd); asyncEvent = this.GetNextEvent(); flag3 = (asyncEvent != null); } } } finally { this.currentlyExecuting = false; this.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.RunEnd); if (budget != null) { try { budget.Dispose(); } catch (FailFastException arg) { AirSyncDiagnostics.TraceError <FailFastException>(ExTraceGlobals.RequestsTracer, this, "Budget.Dispose failed with exception: {0}", arg); } } } }
public static NotificationManager GetOrCreateNotificationManager(INotificationManagerContext context, IAsyncCommand command, out bool wasTakenOver) { string text = NotificationManager.GetUniqueId(context); uint num = context.PolicyKey; int mailboxPolicyHash = context.MailboxPolicyHash; wasTakenOver = false; NotificationManager notificationManager = null; NotificationManager notificationManager2 = null; lock (NotificationManager.notificationManagerCache) { bool flag2 = NotificationManager.notificationManagerCache.TryGetValue(text, out notificationManager2); if (flag2) { NotificationManager.hitsPerMinute.Add(1U); } if (flag2 && notificationManager2.subscriptionCanBeTaken && !notificationManager2.MailboxLoggingEnabled && mailboxPolicyHash == notificationManager2.policyHashCode && num == notificationManager2.policyKey) { wasTakenOver = true; } else { if (flag2) { NotificationManager.cacheContentionsPerMinute.Add(1U); notificationManager2.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Removed); NotificationManager.notificationManagerCache.Remove(text); NotificationManager.removedInstances[text] = notificationManager2; notificationManager = notificationManager2; } notificationManager2 = new NotificationManager(command, text, mailboxPolicyHash, num); NotificationManager.createsPerMinute.Add(1U); notificationManager2.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Cached); NotificationManager.notificationManagerCache.Add(text, notificationManager2); AirSyncCounters.NumberOfNotificationManagerInCache.RawValue = (long)NotificationManager.notificationManagerCache.Count; } } if (notificationManager != null) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, notificationManager2, "Disposing existing NotificationManager for {0}", text); notificationManager.EnqueueEvent(new NotificationManager.AsyncEvent(NotificationManager.AsyncEventType.Acquire, null)); notificationManager.EnqueueDispose(); notificationManager = null; } if (wasTakenOver) { NotificationManager.AsyncEvent evt = new NotificationManager.AsyncEvent(NotificationManager.AsyncEventType.Acquire, command); if (!notificationManager2.EnqueueEvent(evt)) { AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, notificationManager2, "A NotificationManager was attempted to be taken over but failed for {0}", text); wasTakenOver = false; notificationManager2 = NotificationManager.CreateNotificationManager(context, command); } else { notificationManager2.EnqueueDiagOperation(NotificationManager.DiagnosticEvent.Stolen); NotificationManager.stealsPerMinute.Add(1U); } } AirSyncDiagnostics.TraceDebug <string>(ExTraceGlobals.ThreadingTracer, notificationManager2, "Got or created notification manager for {0}", text); return(notificationManager2); }