/// <summary> /// Add a dispatcher to blocked dispatcher list /// </summary> /// <param name="dispatcherInfo">dispatcher info</param> private void AddBlockedDispatcher(DispatcherInfo dispatcherInfo) { try { dispatcherInfo.BlockTime = DateTime.Now; this.blockedDispatcherDic.Add(dispatcherInfo.UniqueId, dispatcherInfo); // if a dispatcher has never been blocked, take it as "young" blocked disaptcher. if (dispatcherInfo.BlockRetryCount <= 0) { BrokerTracing.TraceVerbose("[DispatcherManager] Increment youngBlockedDispatcherCount, task id={0}, BlockRetryCount={1}", dispatcherInfo.UniqueId, dispatcherInfo.BlockRetryCount); this.youngBlockedDispatcherCount++; } this.blockedDispatcherQueue.Enqueue(dispatcherInfo); if (this.blockedDispatcherQueue.Count == 1) { BrokerTracing.TraceVerbose("[DispatcherManager] Block dispatcher: change unblock timer, task id = {0}", dispatcherInfo.UniqueId); this.unblockTimer.Change(this.blockTimeSpan, TimeSpan.FromMilliseconds(-1)); } BrokerTracing.TraceInfo("[DispatcherManager] Add dispatcher {0} into the blocked dispatcher list.", dispatcherInfo.UniqueId); } catch (ArgumentException) { BrokerTracing.TraceError("[DispatcherManager] Dispatcher {0} already exist in the blocked dispatcher list.", dispatcherInfo.UniqueId); } }
/// <summary> /// Exit concurrency controlled section. /// </summary> public static void Exit() { BrokerTracing.TraceInfo("[MSMQConcurrencyController] exit conccurrency controlled section"); object nextCallbackItem = null; lock (SyncObject) { if (concurrency <= 0) { System.Diagnostics.Debug.Assert(false, "Concurrency is not positive"); } if (WaitingCallbacks.Count == 0) { concurrency--; } else { nextCallbackItem = WaitingCallbacks.Dequeue(); } } if (nextCallbackItem != null) { BrokerTracing.TraceInfo("[MSMQConcurrencyController] schedule next waiting callback"); object[] objs = (object[])nextCallbackItem; WaitCallback callback = (WaitCallback)objs[0]; object callbackState = objs[1]; ThreadPool.QueueUserWorkItem(callback, callbackState); } }
internal void RemoveBrokerQueue(BrokerQueue queue) { if (queue != null) { bool containsQueue; lock (this.needDispatchQueueClientIdTable) { containsQueue = this.needDispatchQueueClientIdTable.ContainsKey(queue.ClientId); } if (containsQueue) { try { lock (this.needDispatchQueueClientIdTable) { this.needDispatchQueueClientIdTable.Remove(queue.ClientId); } } catch (Exception e) { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .RemoveBrokerQueue: Remove the broker queue with the client id, {0}, from the client table raised exception, {1}", queue.ClientId, e); } } lock (this.waitBrokerQueuesForPeekRequests) { this.waitBrokerQueuesForPeekRequests.Remove(queue); } } }
public void RegisterReemit(TimeSpan dueTime, int resendLimit, Action <BrokerQueueItem> reemit) { if (this.ReemitToken == null) { this.ReemitToken = ReemitToken.GetToken(); } BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .RegisterReemit: Message {0}", Utility.GetMessageIdFromMessage(this.Message)); this.ReemitTimer = new Timer(t => { if (resendLimit + 1 > this.TryCount && this.ReemitToken.Available) { var clonedRequest = (BrokerQueueItem)this.Clone(); BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .RegisterReemit: Message emit callback old messageid {0}, new messageid {1}, TryCount {2}, ResendLimit {3}", Utility.GetMessageIdFromMessage(this.Message), Utility.GetMessageIdFromMessage(clonedRequest.Message), this.TryCount, resendLimit); if (clonedRequest.ReemitToken.Available) { reemit(clonedRequest); } } }, null, dueTime, TimeSpan.FromMilliseconds(-1)); }
/// <summary> /// Gets the broker frontend /// </summary> /// <param name="callbackInstance">indicating response service callback</param> /// <returns>returns the broker frontend instance</returns> public IBrokerFrontend GetFrontendForInprocessBroker(IResponseServiceCallback callbackInstance) { BrokerTracing.TraceInfo("[BrokerEntry] GetFrontendForInprocessBroker..."); try { if (this.closeFlag != 0) { if (this.cleanData) { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerUnavailable, SR.BrokerIsUnavailable); } else { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending); } } this.sharedData.WaitForInitializationComplete(); BrokerTracing.TraceInfo("[BrokerEntry] GetFrontendForInprocessBroker successfully."); return(new BrokerController(this.clientManager, callbackInstance, this.observer)); } catch (Exception e) { BrokerTracing.TraceError("[BrokerEntry] GetFrontendForInprocessBroker failed: {0}", e); throw; } }
/// <summary> /// Informs that a client is attaching to this broker /// </summary> public void Attach() { BrokerTracing.TraceInfo("[BrokerEntry] Client attached."); try { // Bug 8379: If closing is under going, returns broker suspending exception and let broker manager try again latter. if (this.closeFlag != 0) { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending); } this.stateManager.Attach(); this.monitor.Attach(); BrokerTracing.TraceInfo("[BrokerEntry] Client attached successfully."); } catch (NullReferenceException) { // Bug 8379: NullReferenceException caught because closing procedure is on going, returns broker suspending exception instead so that broker manager could properly handle ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending); } catch (Exception e) { BrokerTracing.TraceError("[BrokerEntry] Client attached failed: {0}", e); throw; } }
/// <summary> /// Pull responses /// </summary> /// <param name="position">indicating the position</param> /// <param name="count">indicating the count</param> /// <returns>broker response messages</returns> public BrokerResponseMessages PullResponses(GetResponsePosition position, int count) { this.result = new PullResponseMessage(count, this.Queue, this.ConvertMessage, this.ResetTimeout, this.SharedData); if (position == GetResponsePosition.Begin) { this.Queue.ResetResponsesCallback(); this.ResponsesCount = 0; } BrokerResponseMessages responseMessages; if (this.Queue.RegisterResponsesCallback(this.result.ReceiveResponse, OperationContext.Current.IncomingMessageVersion, GenerateResponseActionFilter(this.Action), count, null)) { this.result.CompleteEvent.WaitOne(); responseMessages = this.result.Message; } else { responseMessages = this.result.Message; responseMessages.EOM = true; } BrokerTracing.TraceInfo("[PullResponsesHandler] Pull responses finished, Count = {0}", responseMessages.SOAPMessage.Length); this.IncreaseResponsesCount(responseMessages.SOAPMessage.Length); return(responseMessages); }
/// <summary> /// Initializes a new instance of the BrokerObserver class /// </summary> /// <param name="sharedData">indicating the shared data</param> /// <param name="clientInfoList">indicating the client info list</param> public BrokerObserver(SharedData sharedData, ClientInfo[] clientInfoList) { this.callsObserver = new ObserverItem(BrokerPerformanceCounterKey.Calculations); this.faultedCallsObserver = new ObserverItem(BrokerPerformanceCounterKey.Faults); this.incomingRequestObserver = new ObserverItem(BrokerPerformanceCounterKey.RequestMessages); this.outgoingResponseObserver = new ObserverItem(BrokerPerformanceCounterKey.ResponseMessages); this.callDurationObserver = new ObserverItem(BrokerPerformanceCounterKey.None); this.purgedTotal = sharedData.BrokerInfo.PurgedTotal; this.purgedProcessed = sharedData.BrokerInfo.PurgedProcessed; this.purgedFailed = sharedData.BrokerInfo.PurgedFailed; this.total = this.purgedTotal; this.processed = this.purgedProcessed; this.faultedCallsObserver.Increment(this.purgedFailed); foreach (ClientInfo info in clientInfoList) { this.total += info.TotalRequestsCount; this.processed += info.ProcessedRequestsCount; this.faultedCallsObserver.Increment(info.FailedRequestsCount); } this.enableThrottling = !sharedData.BrokerInfo.Durable; this.messageThrottleStartThreshold = sharedData.Config.Monitor.MessageThrottleStartThreshold; this.messageThrottleStopThreshold = sharedData.Config.Monitor.MessageThrottleStopThreshold; BrokerTracing.TraceInfo("[BrokerObserver] Initial counter: Total = {0}, Processed = {1}, Failed = {2}, PurgedTotal = {3}, PurgedProcessed = {4}, PurgedFailed = {5}", this.total, this.processed, this.faultedCallsObserver.Total, this.purgedTotal, this.purgedProcessed, this.purgedFailed); }
/// <summary> /// Create storage queue /// </summary> /// <param name="queue">storage queue</param> /// <remarks> /// CreateIfNotExist method throws StorageClientException when queue is /// being deleted, so sleep for a while before retry. /// </remarks> public static void CreateQueueWithRetry(CloudQueue queue) { RetryHelper <object> .InvokeOperation( () => { if (queue.CreateIfNotExists()) { BrokerTracing.TraceInfo("[AzureQueueManager].CreateQueueWithRetry: Create the queue {0}", queue.Name); } return(null); }, (e, count) => { BrokerTracing.TraceError("Failed to create the queue {0}: {1}. Retry Count = {2}", queue.Name, e, count); StorageException se = e as StorageException; if (se != null) { if (BurstUtility.GetStorageErrorCode(se) == QueueErrorCodeStrings.QueueAlreadyExists) { Thread.Sleep(TimeSpan.FromMinutes(1)); } } }); }
/// <summary> /// Create storage blob container. /// </summary> /// <param name="container">blob container</param> public static void CreateContainerWithRetry(CloudBlobContainer container) { RetryHelper <object> .InvokeOperation( () => { if (container.CreateIfNotExists()) { BrokerTracing.TraceInfo("[AzureQueueManager].CreateContainerWithRetry: Create the container {0}", container.Name); } return(null); }, (e, count) => { BrokerTracing.TraceError("Failed to create the container {0}: {1}. Retry Count = {2}", container.Name, e, count); StorageException se = e as StorageException; if (se != null) { string errorCode = BurstUtility.GetStorageErrorCode(se); // According to test, the error code is ResourceAlreadyExists. // There is no doc about this, add ContainerAlreadyExists here. // TODO: Azure storage SDK 2.0 if ( // errorCode == StorageErrorCodeStrings.ResourceAlreadyExists || errorCode == StorageErrorCodeStrings.ContainerAlreadyExists) { Thread.Sleep(TimeSpan.FromMinutes(1)); } } }); }
public Message ReceiveRequest() { BrokerTracing.TraceInfo("[AzureQueueProxy] ReceiveRequest is called"); Message request = null; try { while (!this.requestMessageQueue.TryTake(out request, RequestWaitIntervalMs)) { BrokerTracing.TraceInfo("[AzureQueueProxy] No message in the request message queue. Block wait."); } } catch (ObjectDisposedException) { BrokerTracing.TraceWarning("[AzureQueueProxy] requestMessageQueue is disposed."); return(null); } // while (!requestMessageQueue.TryDequeue(out request)) // { // BrokerTracing.TraceInfo("[AzureQueueProxy] No message in the request message queue. Sleep wait."); // Thread.Sleep(RequestWaitIntervalMs); // } BrokerTracing.TraceInfo("[AzureQueueProxy] Request is dequeued {0}", request.Version.ToString()); return(request); }
/// <summary> /// Process a collection of queue messages. /// </summary> /// <param name="messages">collection of the queue messages</param> private void ProcessMessages(IEnumerable <CloudQueueMessage> messages) { BrokerTracing.TraceInfo(SoaHelper.CreateTraceMessage("Proxy", "ProcessMessages", string.Format("Process {0} messages.", messages.Count <CloudQueueMessage>()))); messages.AsParallel <CloudQueueMessage>() .ForAll <CloudQueueMessage>( (requestQueueMessage) => { Message request = null; try { BrokerTracing.TraceInfo(string.Format("SOA broker proxy perf1 - {0}", DateTime.UtcNow.TimeOfDay.TotalSeconds)); request = this.requestStorageClients.First().GetWcfMessageFromQueueMessage(requestQueueMessage); this.requestMessageQueue.Add(request); // this.requestMessageQueue.Enqueue(request); UniqueId messageId = SoaHelper.GetMessageId(request); BrokerTracing.TraceInfo(SoaHelper.CreateTraceMessage("Proxy", "Request received inqueue", string.Empty, messageId, "Request message in queue")); } catch (Exception e) { BrokerTracing.TraceError(SoaHelper.CreateTraceMessage("Proxy", "ProcessMessages", string.Format("Error occurs {0}", e))); } }); this.semaphoreForWorker.Release(); }
internal void AddToRemovedDispatcherIds(string taskId) { if (this.removedDispatcherIds.Add(taskId)) { BrokerTracing.TraceInfo("Added task {0} to removedDispatcherIds list.", taskId); } }
/// <summary> /// Start the timer. /// </summary> private void TriggerTimer() { if (this.stop) { lock (this.timerStopLock) { if (this.stop) { this.timerStopped = true; BrokerTracing.TraceInfo( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "TriggerTimer", "Worker stops.")); return; } else { this.timerStopped = false; } } } try { BrokerTracing.TraceInfo( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "TriggerTimer", "Timer triggered with sleep time {0}.", this.sleepPeriod)); this.timer.Change(this.sleepPeriod, Timeout.Infinite); if (this.sleepPeriod == 0) { this.sleepPeriod = MinSleepTime; } else { this.sleepPeriod *= 2; if (this.sleepPeriod > MaxSleepTime) { this.sleepPeriod = MaxSleepTime; } } } catch (NullReferenceException) { TraceUtils.TraceWarning( "MessageSender.Worker", "TriggerTimer", "NullReferenceException occurs when timer is being disposed."); } catch (Exception e) { TraceUtils.TraceError("MessageSender.Worker", "TriggerTimer", "Error occurs, {0}", e); } }
/// <summary> /// Initializes a new instance of the BrokerStateManager class /// </summary> /// <param name="sharedData">indicating the shared data</param> /// <param name="clientAvaliable">indicating whether there is client avaliable when starting up</param> public BrokerStateManager(SharedData sharedData, bool clientAvaliable) { this.sharedData = sharedData; this.timeoutManager = new TimeoutManager("BrokerStateManager"); this.state = BrokerState.Started; this.timeoutManager.RegisterTimeout(this.sharedData.Config.Monitor.ClientConnectionTimeout, clientAvaliable ? new WaitCallback(this.TimeoutToSuspended) : new WaitCallback(this.TimeoutToFinish), null); BrokerTracing.TraceInfo("[BrokerStateManager] Successfully initialized BrokerStateManager: State = {0}", this.state); }
/// <summary> /// Informs that a frontend has connected /// </summary> /// <param name="instance">indicating the frontend instance</param> public void FrontendConnected(object instance, object frontend) { BrokerTracing.TraceInfo("[BrokerClient] Client {0}: Frontend connected: {1} ({2}).", this.clientId, instance.ToString(), instance.GetHashCode()); lock (this.connectedInstance) { this.connectedInstance.Add(instance, frontend); } }
private bool HandleResponseWithoutAsyncToken(BrokerQueue queue, BrokerQueueItem requestItem) { bool isHandled = false; Guid persistId = requestItem.PersistId; object asyncToken = requestItem.PersistAsyncToken.AsyncToken; int dispatcherNumber = requestItem.DispatchNumber; if (asyncToken != null && this.responsesWithoutAsyncTokenTable.Count > 0) { bool needPutResponse = false; DispatcherAsyncTokenItem asyncTokenItem = null; try { lock (this.responsesWithoutAsyncTokenTable) { this.responsesWithoutAsyncTokenTable.TryGetValue(persistId, out asyncTokenItem); } if (asyncTokenItem != null) { lock (this.responsesWithoutAsyncTokenTable) { this.responsesWithoutAsyncTokenTable.Remove(persistId); } needPutResponse = true; lock (this.requestsAsyncTokenTable) { this.requestsAsyncTokenTable.Remove(persistId); } } } catch (Exception e) { if (needPutResponse) { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: fail to remove the async token from the table, Exception: {0}", e); } else { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PrefetchRequestCallback: can not get the response async token, Exception: {0}", e); } } if (needPutResponse && dispatcherNumber == 0) { asyncTokenItem.PersistAsyncToken.AsyncToken = asyncToken; queue.PutResponseAsync(asyncTokenItem.Message, requestItem); isHandled = true; } } return(isHandled); }
/// <summary> /// Triggers for queue events /// </summary> /// <param name="sender">indicating the sender</param> /// <param name="e">indicating the event args</param> private void Queue_OnPutResponsesSuccessEvent(object sender, PutResponsesSuccessEventArgs e) { // For both durable session, enable ClientIdleTimeout when all flushed requests are processed if (this.sharedData.BrokerInfo.Durable) { if (this.queue.FlushedRequestsCount == this.queue.ProcessedRequestsCount) { BrokerTracing.TraceInfo( "[BrokerClient] Client {0}: Queue_OnPutResponsesSuccessEvent FlushedRequestsCount {1} ProcessedRequestsCount {2}.", this.clientId, this.queue.FlushedRequestsCount, this.queue.ProcessedRequestsCount); lock (this.lockState) { if (this.state == BrokerClientState.AllRequestDone || this.state == BrokerClientState.ClientConnected || this.state == BrokerClientState.GetResponse) { if (this.queue.FlushedRequestsCount == this.queue.ProcessedRequestsCount) { BrokerTracing.TraceInfo( "[BrokerClient] Client {0}: Restart counting ClientIdleTimeout because all flushed requests are processed.", this.clientId); this.timeoutManager.RegisterTimeout(this.sharedData.Config.Monitor.ClientIdleTimeout, this.TimeoutToDisconnected, this.state); } } } } } else // For interactive session, enable ClientIdleTimeout when all requests are processed { if (this.queue.AllRequestsCount == this.queue.ProcessedRequestsCount) { BrokerTracing.TraceInfo( "[BrokerClient] Client {0}: Queue_OnPutResponsesSuccessEvent AllRequestsCount {1} ProcessedRequestsCount {2}.", this.clientId, this.queue.AllRequestsCount, this.queue.ProcessedRequestsCount); lock (this.lockState) { if (this.state == BrokerClientState.AllRequestDone || this.state == BrokerClientState.ClientConnected || this.state == BrokerClientState.GetResponse) { if (this.queue.AllRequestsCount == this.queue.ProcessedRequestsCount) { BrokerTracing.TraceInfo( "[BrokerClient] Client {0}: Restart counting ClientIdleTimeout because all requests are processed.", this.clientId); this.timeoutManager.RegisterTimeout(this.sharedData.Config.Monitor.ClientIdleTimeout, this.TimeoutToDisconnected, this.state); } } } } } }
public void SendResponse(Message response) { BrokerTracing.TraceInfo("[AzureQueueProxy] Response is inqueued {0}", response.Version.ToString()); // for azure queue need to copy a new message MessageBuffer messageBuffer = null; messageBuffer = response.CreateBufferedCopy(int.MaxValue); Message m = messageBuffer.CreateMessage(); this.responseMessageQueue.Enqueue(m); }
/// <summary> /// Gets the broker controller instance /// </summary> /// <returns>returns the broker controller instance</returns> private BrokerController GetInstance() { if (this.singletonInstance == null) { BrokerTracing.TraceInfo("[ControllerFrontendProvider] GetInstance."); return(new BrokerController(false, this.clientManager, this.brokerAuth, this.observer, this.azureQueueProxy)); } else { return(this.singletonInstance); } }
public void SendResponse(Message response, string clientData) { BrokerTracing.TraceInfo("[AzureQueueProxy] Response is inqueued with clientData {0}", response.Version.ToString()); // for azure queue need to copy a new message MessageBuffer messageBuffer = null; messageBuffer = response.CreateBufferedCopy(int.MaxValue); Message m = messageBuffer.CreateMessage(); this.responseMessageClients[this.sessionClientData[clientData]].Item1.Enqueue(m); }
/// <summary> /// remove the broker queue from the cached list. /// </summary> /// <param name="clientId">the client id.</param> internal void RemovePersistQueueByClient(string clientId) { ParamCheckUtility.ThrowIfNull(clientId, "clientId"); BrokerTracing.TraceInfo("[BrokerQueueFactory] .RemovePersistQueueByClient: ClientId:{0}", clientId); lock (this.clientBrokerQueueDic) { if (this.clientBrokerQueueDic.ContainsKey(clientId)) { this.clientBrokerQueueDic.Remove(clientId); } } }
/// <summary> /// Releases the instance /// </summary> /// <param name="instanceContext">indicating the instance context</param> /// <param name="instance">indicating the instance</param> public void ReleaseInstance(InstanceContext instanceContext, object instance) { // Only release the instance if it is not a singleton if (this.singletonInstance == null) { BrokerTracing.TraceInfo("[ControllerFrontendProvider] Release instance."); IDisposable disposableInstance = instance as IDisposable; if (disposableInstance != null) { disposableInstance.Dispose(); } } }
/// <summary> /// Informs that all clients have disconnectted /// </summary> public void AllClientsDisconnected() { BrokerTracing.TraceInfo("[BrokerStateManager] All clients have disconnectted."); lock (this.lockState) { if (this.state == BrokerState.Running) { BrokerTracing.TraceInfo("[BrokerStateManager] State: Running ==> Idle"); this.state = BrokerState.Idle; this.timeoutManager.RegisterTimeout(this.sharedData.Config.Monitor.SessionIdleTimeout, this.TimeoutToSuspended, null); } } }
/// <summary> /// Informs that a client has connectted /// </summary> public void ClientConnected() { BrokerTracing.TraceInfo("[BrokerStateManager] A client has connectted."); lock (this.lockState) { if (this.state == BrokerState.Started || this.state == BrokerState.Idle) { BrokerTracing.TraceInfo("[BrokerStateManager] State: {0} ==> Running", this.state); this.state = BrokerState.Running; this.timeoutManager.Stop(); } } }
public void GetRequestAsync(BrokerQueueCallback requestCallback, object state) { ParamCheckUtility.ThrowIfNull(requestCallback, "requestCallback"); bool isCallbackHandled = false; if (this.requestCacheQueue.Count > 0) { BrokerQueueItem request = null; if (!this.requestCacheQueue.TryDequeue(out request)) { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .GetRequestAsync: All cached requests are dispatched."); } if (request != null) { try { #if DEBUG BrokerTracing.TraceVerbose("[BrokerQueueDispatcher] .GetRequestAsync: handle request callback from cache queue. request id={0}", GetMessageId(request)); #endif this.RegisterReemit(request); isCallbackHandled = true; requestCallback(request, state); } catch (Exception e) { this.requestCacheQueue.Enqueue(request); // request callback raise exception. BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .GetRequestAsync: The request callback raise exception. Exception: {0}", e); } } } if (this.requestCacheQueue.Count <= this.watermarkerForTriggerPrefetch) { BrokerTracing.TraceVerbose("[BrokerQueueDispatcher] .GetRequestAsync (perf): Trigger prefetch because the count of cached items is below threshold. state={0}", (int)state); this.TriggerPrefetch(); } if (!isCallbackHandled) { this.requestCallbackQueue.Enqueue(new BrokerQueueCallbackItem(requestCallback, state)); // in case the last request come in the cache queue right before the request callback enqueue. this.HandlePendingRequestCallback(); } }
/// <summary> /// Ask the broker manager to close this broker /// </summary> /// <param name="suspend">indicating whether to suspend</param> internal void UnloadBroker(bool suspend) { BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[BrokerEntry] Unload broker domain, ID = {0}", this.sharedData.BrokerInfo.SessionId); try { this.Close(!suspend).GetAwaiter().GetResult(); BrokerTracing.TraceInfo("[BrokerEntry] Self Cleanup: Close succeeded"); } catch (Exception e) { BrokerTracing.TraceWarning("[BrokerEntry] Self Cleanup: Close failed: {0}", e); } }
/// <summary> /// EndOfMessage arrives /// </summary> /// <param name="msgCount">indicating the msg count</param> /// <param name="timeout">indicating the timeout</param> public void EndOfMessage(long msgCount, int batchId, int timeout) { lock (this.lockState) { if (this.state != BrokerClientState.ClientConnected) { BrokerTracing.EtwTrace.LogBrokerClientRejectEOM(this.sharedData.BrokerInfo.SessionId, this.clientId, this.state.ToString()); switch (this.state) { case BrokerClientState.GetResponse: ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMReject_GetResponse, SR.EOMReject_GetResponse); break; case BrokerClientState.EndRequests: ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMReject_EndRequests, SR.EOMReject_EndRequests); break; default: ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMRejected, SR.EOMRejected, this.state.ToString()); break; } } // Stop the timer this.timeoutManager.Stop(); try { this.Flush(msgCount, batchId, timeout, true); } catch (Exception e) { BrokerTracing.TraceError("[BrokerClient] Failed to flush messages: {0}", e); // If EndRequests throws exception from broker queue, the // timer is closed and never reactivated without user action. // Thus, the broker client would leak forever and the broker // process would run away if user does not purge the client // or close the session later. this.timeoutManager.RegisterTimeout(this.sharedData.Config.Monitor.ClientIdleTimeout, this.TimeoutToDisconnected, this.state); throw; } // State will change if flush succeeded // If flush failed, the state won't change BrokerTracing.TraceInfo("[BrokerClient] Client {0}: State: ClientConnected ==> EndOfMessage", this.clientId); this.state = BrokerClientState.EndRequests; this.endOfMessageCalled = true; } }
/// <summary> /// Returns one ServieClient in the pool. /// </summary> private AzureServiceClient InternalGetProxyClient() { AzureServiceClient client = null; if (!this.IsFull) { client = new AzureServiceClient(ProxyBinding.BrokerProxyBinding, this.proxyEpr); BrokerTracing.TraceInfo( "[ProxyClientPool].InternalGetProxyClient: Create a new client, {0}, {1}", client, client.ServiceClient.Endpoint.Address); this.clientPool.Add(client); BrokerTracing.TraceInfo( "[ProxyClientPool].InternalGetProxyClient: Pool size is {0}", this.clientPool.Count); // add "1" to the RefCounts list since we will return this new client this.clientRefCounts.Add(1); return(client); } else { int poolSize = this.clientPool.Count; if (poolSize > 0) { if (this.currentIndex <= 0 || this.currentIndex >= poolSize) { this.currentIndex = 0; } client = this.clientPool[this.currentIndex]; this.clientRefCounts[this.currentIndex]++; this.currentIndex++; } BrokerTracing.TraceInfo( "[ProxyClientPool].InternalGetProxyClient: Get a client from pool, {0}, {1}", client, client.ServiceClient.Endpoint.Address); return(client); } }
/// <summary> /// stop the dispatchers prefetching. /// </summary> /// <param name="taskIds">the task ids identifying the dispatchers to stop</param> /// <param name="availableToShutdownTaskIds">true if resume the remaining dispatchers.</param> public void StopDispatchers(IEnumerable <string> availableToShutdownTaskIds, IEnumerable <string> tasksInInterest, bool resumeRemaining = true) { lock (this.lockThis) { Debug.Assert(availableToShutdownTaskIds != null); Debug.Assert(tasksInInterest == null || !availableToShutdownTaskIds.Except(tasksInInterest).Any(), "availableToShutdownTaskIds is not subset of tasksInInterest"); // Get dispatchers available to stop. foreach (string taskId in availableToShutdownTaskIds) { Dispatcher dispatcher; if (this.dispatcherDic.TryGetValue(taskId, out dispatcher)) { BrokerTracing.TraceInfo( "[DispatcherManager].StopDispatchers Stop Dispatcher ID = {0}, CoreCount = {1}", dispatcher.TaskId, dispatcher.Info.CoreCount); dispatcher.Stop(); } else { BrokerTracing.TraceInfo( "[DispatcherManager].StopDispatchers ID = {0}. Not Found.", taskId); } } if (resumeRemaining) { HashSet <string> tasksInInterestSet = null; if (tasksInInterest != null) { tasksInInterestSet = new HashSet <string>(tasksInInterest); } HashSet <string> shouldNotResumeDispatcherIds = new HashSet <string>(availableToShutdownTaskIds); // resume the remaining dispatchers foreach (var dispatcher in this.dispatcherDic.Values.Where(d => TaskInInterestUtil.IsTaskInInterest(tasksInInterestSet, d.TaskId) && !shouldNotResumeDispatcherIds.Contains(d.TaskId))) { if (!shouldNotResumeDispatcherIds.Contains(dispatcher.TaskId)) { dispatcher.Resume(); } } } } }