/// <summary> /// Async method of ProcessMessage. /// </summary> /// <param name="ar">async result</param> /// <returns>response message</returns> public Message EndProcessMessage(IAsyncResult ar) { QueueAsyncResult asyncResult = ar as QueueAsyncResult; Debug.Assert(asyncResult != null, "ar must be a QueueAsyncResult."); using (asyncResult) { UniqueId messageId = asyncResult.MessageId; try { this.manager.RemoveQueueAsyncResult(messageId); } catch (Exception e) { BrokerTracing.TraceError( "[AzureServiceClient].EndProcessMessage: Failed to remove QueueAsyncResult {0}, {1}", messageId, e); } if (asyncResult.Exception != null) { throw asyncResult.Exception; } else { return(asyncResult.ResponseMessage); } } }
/// <summary> /// Add QueueAsyncResult to the dictionary. /// </summary> /// <param name="result">async result</param> /// <param name="requestQueueName">request queue name</param> /// <param name="responseQueueName">response queue name</param> public void AddQueueAsyncResult(QueueAsyncResult result, string requestQueueName, string responseQueueName) { ResponseStorageException e; this.responseQueueNotFound.TryGetValue(responseQueueName, out e); if (e == null) { BrokerTracing.TraceVerbose( "[AzureQueueManager].AddQueueAsyncResult: Add QueueAsyncResult {0} to the dictionary.", result.MessageId); this.callbacks.AddOrUpdate(result.MessageId, result, (key, value) => result); this.requestsMappingToRequestQueue.AddOrUpdate(result.MessageId, requestQueueName, (key, value) => requestQueueName); this.requestsMappingToResponseQueue.AddOrUpdate(result.MessageId, responseQueueName, (key, value) => responseQueueName); } else { BrokerTracing.TraceError( "[AzureQueueManager].AddQueueAsyncResult: Response queue is not found, {0}", responseQueueName); throw e; } }
/// <summary> /// Callback of the CloudQueue.BeginAddMessage method. /// </summary> /// <param name="ar">async result</param> /// <remarks> /// Notice: This method doesn't throw exception. It invokes callback /// and pass exception to it in case exception occurs. /// </remarks> private void BeginAddMessageCallback(IAsyncResult ar) { BrokerTracing.TraceVerbose("[AzureServiceClient].BeginAddMessageCallback: Enter callback method of BeginAddMessage."); var reliableState = ar.AsyncState as ReliableQueueClient.ReliableState; QueueAsyncResult asyncResult = reliableState.State as QueueAsyncResult; Debug.Assert(asyncResult != null, "reliableState.State must be a QueueAsyncResult."); try { BrokerTracing.TraceVerbose( "[AzureServiceClient].BeginAddMessageCallback: Try to complete adding message {0}", asyncResult.MessageId); asyncResult.StorageClient.EndAddMessage(ar); } catch (StorageException e) { BrokerTracing.TraceError( "[AzureServiceClient].BeginAddMessageCallback: Failed to complete adding message {0}, {1}", asyncResult.MessageId, e.ToString()); if (BurstUtility.IsQueueNotFound(e)) { // StorageException happens here when want to add request // messages, so it must be request queue not found. Handle // the outstanding messages, which are already sent to // request queue, but maybe not got by proxy. And should // consider the multi request queue case when there are // multi azure deployments. this.manager.HandleInvalidRequestQueue(new RequestStorageException(e), this.requestStorageClient.QueueName); } this.manager.CompleteCallback(asyncResult, null, new RequestStorageException(e)); } catch (Exception e) { BrokerTracing.TraceError( "[AzureServiceClient].BeginAddMessageCallback: Failed to complete adding message {0}, {1}", asyncResult.MessageId, e.ToString()); this.manager.CompleteCallback(asyncResult, null, e); } }
/// <summary> /// Async method of ProcessMessage. /// </summary> /// <param name="request">request message</param> /// <param name="callback">callback method</param> /// <param name="asyncState">async state</param> /// <returns>async result</returns> public IAsyncResult BeginProcessMessage(Message request, AsyncCallback callback, object asyncState) { MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue); byte[] messageData = AzureQueueItem.Serialize(buffer.CreateMessage()); QueueAsyncResult asyncResult = new QueueAsyncResult(callback, asyncState); UniqueId messageId = request.Headers.MessageId; asyncResult.MessageId = messageId; asyncResult.StorageClient = this.requestStorageClient; try { BrokerTracing.TraceVerbose( "[AzureServiceClient].BeginProcessMessage: Try to add message {0} to the request queue.", messageId); var reliableState = new ReliableQueueClient.ReliableState(asyncResult, messageId); // Notice: It can happen that response message is back before // EndAddMessage is called on the request message. So // add/update the callback info to AzureQueueManager before // calling BeginAddMessage avoid the issue that response comes // back but can't find callback info. this.manager.AddQueueAsyncResult(asyncResult, this.requestStorageClient.QueueName, this.responseStorageName); this.requestStorageClient.BeginAddMessage(messageData, messageId, this.BeginAddMessageCallback, reliableState); } catch (Exception e) { BrokerTracing.TraceError( "[AzureServiceClient].BeginProcessMessage: Failed to add message {0}, {1}", messageId, e); this.manager.CompleteCallback(asyncResult, null, e); } finally { buffer.Close(); } return(asyncResult); }
/// <summary> /// Invoke the specified callback and delete it from the dictionary. /// </summary> /// <param name="asyncResult">it contains callback info</param> /// <param name="response">response message of the request</param> /// <param name="exception">exception occurred when process the request</param> public void CompleteCallback(QueueAsyncResult asyncResult, Message response, Exception exception) { try { using (asyncResult) { asyncResult.ResponseMessage = response; asyncResult.Exception = exception; asyncResult.Complete(); } } catch (Exception e) { BrokerTracing.TraceError( "[AzureQueueManager].CompleteCallback: Error occurs, {0}", e); } }