/// <summary> /// Create message retriever to monitor the response queue and gets /// messages from it. /// </summary> public void Start() { BrokerTracing.TraceVerbose("[ResponseQueueManager].Start: Try to create response storage."); // Make sure response storage is created, the invoker will send // request messages when this method returns. Following method // is thread safe. this.CreateResponseStorage(); if (Interlocked.CompareExchange(ref this.start, 1, 0) == 0) { BrokerTracing.TraceVerbose( "[ResponseQueueManager].Start, {0}", this.responseStorageName); this.semaphoreForResponse = new Semaphore(0, int.MaxValue); this.semaphoreForWorker = new Semaphore(MessageProcessWorker, MessageProcessWorker); this.messageProcessorTask = Task.Factory.StartNew( () => this.MessageProcessor(this.taskCancellation.Token), this.taskCancellation.Token); this.responseStorageClient = new AzureStorageClient(this.responseQueue, this.responseContainer); this.retriever = new MessageRetriever( this.responseQueue, RetrieverConcurrency, ResponseVisibleTimeout, this.HandleMessages, this.HandleInvalidResponseQueue); this.retriever.Start(); } }
/// <summary> /// Dispose the object. /// </summary> /// <param name="disposing">disposing flag</param> protected override void DisposeInternal() { base.DisposeInternal(); // this only happens when unload broker worker. if (this.retriever != null) { try { this.retriever.Close(); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Closing message retriever queue failed, {0}, {1}", e, this.responseStorageName); } this.retriever = null; } if (this.responseQueue != null) { try { this.responseQueue.Delete(); BrokerTracing.EtwTrace.LogQueueDeleted(this.sessionId, this.responseQueue.Name); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Deleting response queue failed, {0}, {1}", e, this.responseStorageName); } this.responseQueue = null; } if (this.responseContainer != null) { try { this.responseContainer.Delete(); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Deleting response container failed, {0}, {1}", e, this.responseStorageName); } this.responseContainer = null; } if (this.messageProcessorTask != null) { if (this.taskCancellation != null) { try { using (this.taskCancellation) { this.taskCancellation.Cancel(); this.messageProcessorTask.Wait(WaitTimeForTaskInMillisecond, this.taskCancellation.Token); } } catch (Exception e) { BrokerTracing.TraceWarning( "[ResponseQueueManager].Dispose: Cancelling messageProcessorTask failed, {0}, {1}", e, this.responseStorageName); } } try { this.messageProcessorTask.Dispose(); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Disposing messageProcessorTask failed, {0}, {1}", e, this.responseStorageName); } this.messageProcessorTask = null; } if (this.semaphoreForResponse != null) { try { this.semaphoreForResponse.Dispose(); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Disposing semaphoreForResponse failed, {0}, {1}", e, this.responseStorageName); } this.semaphoreForResponse = null; } if (this.semaphoreForWorker != null) { try { this.semaphoreForWorker.Dispose(); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Disposing semaphoreForWorker failed, {0}, {1}", e, this.responseStorageName); } this.semaphoreForWorker = null; } if (this.responseStorageClient != null) { try { this.responseStorageClient.Dispose(); } catch (Exception e) { BrokerTracing.TraceError( "[ResponseQueueManager].Dispose: Disposing responseStorageClient failed, {0}, {1}", e, this.responseStorageName); } this.responseStorageClient = null; } }