/// <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> /// Async method for add message. If the message size hits limit, store /// it in blob and add a referral message in queue. /// </summary> /// <param name="messageData">raw data of message</param> /// <param name="messageId">wcf message Id</param> /// <param name="callback">callback method</param> /// <param name="state">state object</param> /// <returns>async state</returns> public IAsyncResult BeginAddMessage(byte[] messageData, UniqueId messageId, AsyncCallback callback, ReliableQueueClient.ReliableState state) { CloudQueueMessage message = new CloudQueueMessage(messageData); try { if (messageData.Length <= MessageSizeBoundary) { message = new CloudQueueMessage(messageData); return(this.ReliableQueue.BeginAddMessage(message, callback, state)); } } catch (ArgumentException e) { // according to the test, when payload is <= 48KB, it can fit // in a queue message. otherwise, ArgumentException occurs. but // there is no doc about this. so catch ArgumentException here, // and store message to blob below. TraceUtils.TraceWarning("AzureStorageClient", "BeginAddMessage", "BeginAddMessage failed, {0}", e); } catch (Exception ex) { TraceUtils.TraceWarning("AzureStorageClient", "BeginAddMessage", "BeginAddMessage failed, {0}", ex); throw; } TraceUtils.TraceVerbose("AzureStorageClient", "BeginAddMessage", "Upload message {0} to storage blob.", messageId); this.UploadBlob(messageData, messageId); // Store a referral message in Azure queue with the same message Id // as the original message. It redirects proxy to get real message // from the blob. Message referralMessage = Message.CreateMessage(MessageVersion.Default, string.Empty); referralMessage.Headers.MessageId = messageId; referralMessage.Headers.Add( MessageHeader.CreateHeader(Constant.MessageHeaderBlob, Constant.HpcHeaderNS, string.Empty)); message = new CloudQueueMessage(AzureQueueItem.Serialize(referralMessage)); return(this.ReliableQueue.BeginAddMessage(message, callback, state)); }