/// <summary> /// the helper method to initialize the BrokerQueueItem instance. /// </summary> /// <param name="context">the request context.</param> /// <param name="msg">the message.</param> /// <param name="persistId">the persist id.</param> /// <param name="asyncState">the async state object.</param> private void Intialize(RequestContextBase context, Message msg, Guid persistId, object asyncState) { this.context = context; if (msg != null) { this.buffer = msg.CreateBufferedCopy(BrokerEntry.MaxMessageSize); msg.Close(); } this.persistGuid = persistId; this.asyncState = asyncState; this.asyncToken = new BrokerQueueAsyncToken(this.persistGuid, asyncState, null, 0); }
/// <summary> /// Initializes a new instance of the PersistMessage class for deserialization. /// </summary> /// <param name="info">the serializaion info.</param> /// <param name="context">the serialization context.</param> protected BrokerQueueItem(SerializationInfo info, StreamingContext context) { ParamCheckUtility.ThrowIfNull(info, "info"); MessageVersion version = DeserializeMessageVersion(info.GetInt32(MessageVersionTag)); using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader((byte[])info.GetValue(BrokerQueueItem.MessageTag, typeof(byte[])), BrokerEntry.ReaderQuotas)) { using (Message messageTmp = Message.CreateMessage(reader, BrokerEntry.MaxMessageSize, version)) { this.buffer = messageTmp.CreateBufferedCopy(BrokerEntry.MaxMessageSize); } } int deserializeFlags = 0; foreach (SerializationEntry entry in info) { switch (entry.Name) { case BrokerQueueItem.AsyncStateTag: this.asyncState = BrokerQueueItem.DeserializeObject(entry); deserializeFlags |= 1; break; case BrokerQueueItem.PersistIdTag: this.persistGuid = (Guid)BrokerQueueItem.DeserializeObject(entry); deserializeFlags |= 2; break; } if (deserializeFlags == 3) { break; } } this.context = BrokerQueueItem.DummyRequestContextField; this.asyncToken = new BrokerQueueAsyncToken(this.persistGuid, this.asyncState, null, 0); }
/// <summary> /// Initializes a new instance of the DispatcherAsyncTokenItem class /// </summary> /// <param name="msg">the message.</param> /// <param name="persistAsyncToken">the persist async token.</param> public DispatcherAsyncTokenItem(Message msg, BrokerQueueAsyncToken persistAsyncToken) { this.message = msg; this.persistAsyncToken = persistAsyncToken; }
public void PutResponseAsync(Message responseMsg, BrokerQueueItem requestItem, bool ignoreAsyncToken = false) { try { // Null means the request has been put back. if (responseMsg != null && this.sharedData.Config.LoadBalancing.MessageResendLimit > 0) { if (!requestItem.ReemitToken.Finish()) { TraceUtils.TraceWarning( "BrokerQueueDispatcher", "PutResponseAsync", "Drop the response {0} since no multi emission callback registered", Utility.GetMessageIdFromMessage(requestItem.Message)); return; } } BrokerQueueAsyncToken asyncToken = requestItem.PersistAsyncToken; if (asyncToken.AsyncToken != null || ignoreAsyncToken || responseMsg == null) { asyncToken.Queue.PutResponseAsync(responseMsg, requestItem); return; } DispatcherAsyncTokenItem asyncTokenItem = null; lock (this.requestsAsyncTokenTable) { this.requestsAsyncTokenTable.TryGetValue(asyncToken.PersistId, out asyncTokenItem); } if (asyncTokenItem != null) { bool hasGetAsyncToken = false; try { if (asyncTokenItem != null) { if (asyncTokenItem.AsyncToken != null) { asyncToken.AsyncToken = asyncTokenItem.AsyncToken; hasGetAsyncToken = true; lock (this.requestsAsyncTokenTable) { this.requestsAsyncTokenTable.Remove(asyncToken.PersistId); } } } } catch (Exception e) { if (hasGetAsyncToken) { BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .PutResponseAsync: remove the async token from the table raised the exception, {0}", e); } else { // maybe there are duplicate responses, and the request in the async token table is removed by the previous request. BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .PutResponseAsync: try to get the async token from the table raised the exception, {0}", e); } } if (hasGetAsyncToken) { asyncToken.Queue.PutResponseAsync(responseMsg, requestItem); } else { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PutResponseAsync: Failed to get async token."); lock (this.responsesWithoutAsyncTokenTable) { this.responsesWithoutAsyncTokenTable.Add(asyncToken.PersistId, new DispatcherAsyncTokenItem(responseMsg, asyncToken)); } if (asyncTokenItem.AsyncToken != null) { bool needPutToTheQueue = false; try { lock (this.responsesWithoutAsyncTokenTable) { this.responsesWithoutAsyncTokenTable.Remove(asyncToken.PersistId); } needPutToTheQueue = true; lock (this.requestsAsyncTokenTable) { this.requestsAsyncTokenTable.Remove(asyncToken.PersistId); } } catch (Exception e) { if (needPutToTheQueue) { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PutResponseAsync: remove the request async token from the table failed, the exception: {0}", e); } else { // in case the reponse message is persisted by another thread. BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .PutResponseAsync: remove the response from the responses without async table fail, the exception: {0}", e); } } if (needPutToTheQueue) { asyncToken.AsyncToken = asyncTokenItem.AsyncToken; asyncToken.Queue.PutResponseAsync(responseMsg, requestItem); } else { BrokerTracing.TraceWarning( "[BrokerQueueDispatcher] .PutResponseAsync: Don't put response back because needPutToTheQueue=false. AsyncToken.PersistId={0}, requestItem id: {1}, response id:{2}", asyncToken.PersistId, requestItem?.Message?.Headers?.MessageId, responseMsg?.Headers?.MessageId); } } else { // the request item is processed and its response is returned, but its async token is unknown yet. At this point, as corresponding DispatcherAsyncToken item is // already put into responsesWithoutAsyncTokenTable, the request item itself is of no use now. so dispose it. BrokerTracing.TraceInfo( "[BrokerQueueDispatcher] .PutResponseAsync: Dispose requestItem id: {0}, response id:{1}", requestItem?.Message?.Headers?.MessageId, responseMsg?.Headers?.MessageId); requestItem.Dispose(); } } } else { BrokerTracing.TraceError("[BrokerQueueDispatcher] .PutResponseAsync: can not find the async token."); } } catch (Exception e) { BrokerTracing.TraceError("[BrokerQueueDispatcher] .PutResponseAsync: unkown exception, {0}", e); } }