/// <summary> /// Reply response /// </summary> /// <param name="ar">async result</param> private void ReplyResponse(IAsyncResult ar) { // No need to handle exceptions here object[] objArr = (object[])ar.AsyncState; string sessionId = (string)objArr[0]; RequestContextBase context = (RequestContextBase)objArr[1]; Message message = (Message)objArr[2]; Guid messageId = (Guid)objArr[3]; bool isFault = SafeGetIsFault(message); // close message message.Close(); try { context.EndReply(ar); BrokerTracing.EtwTrace.LogFrontEndResponseSent(sessionId, context.CorrespondingBrokerClient.ClientId, messageId); } catch (Exception e) { BrokerTracing.EtwTrace.LogFrontEndResponseSentFailed(sessionId, context.CorrespondingBrokerClient.ClientId, messageId, e.ToString()); // Should we swallow? // Swallow the exception } finally { // Why the ReplySent is called twice? this.ReplySent(context, isFault); } }
public WorkItemExposed(WorkItem original, WorkItemTrackingHttpClientBase witClient, RequestContextBase context) { this.current = original ?? throw new ArgumentNullException(nameof(original)); this.witClient = witClient ?? throw new ArgumentNullException(nameof(witClient)); this.context = context; changeLog = new FieldsChangeLog() { WorkItemId = original.Id.GetValueOrDefault(0), RevisionNo = original.Rev.GetValueOrDefault(0) }; }
/// <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> /// Try to reply message /// </summary> /// <param name="sessionId">indicate the session ID</param> /// <param name="context">indicate the request context</param> /// <param name="message">indicate the reply message</param> /// <param name="messageId">indicating the message id</param> private void TryReplyMessage(string sessionId, RequestContextBase context, Message message, Guid messageId) { try { this.observer.RequestProcessingCompleted(); context.BeginReply(message, this.replyResponseCallback, new object[] { sessionId, context, message, messageId }); } catch (Exception e) { bool isFault = SafeGetIsFault(message); // close mesage message.Close(); // Bug 6288: Update counter regardless if reply is sent successfully or not this.ReplySent(context, isFault); BrokerTracing.EtwTrace.LogFrontEndResponseSentFailed(sessionId, context.CorrespondingBrokerClient.ClientId, messageId, e.ToString()); } }
/// <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); }
internal BrokerQueueItem(RequestContextBase context, Message msg, object asyncState) { this.Intialize(context, msg, Guid.NewGuid(), asyncState); }
/// <summary> /// Initializes a new instance of the PersistMessage class for the broker queue. /// </summary> /// <param name="context">the request context.</param> /// <param name="msg">the message(request/response) in the persist item</param> /// <param name="persistId">the persist id.</param> /// <param name="asyncState">the token for write back the response to the client, serializable object</param> internal BrokerQueueItem(RequestContextBase context, Message msg, Guid persistId, object asyncState) { this.Intialize(context, msg, persistId, asyncState); }
/// <summary> /// Put the request item into the storage. and the storage will cache the requests in the memory /// until the front end call the flush method. the async result will return the BrokerQueueItem. /// </summary> /// <param name="context">the request context relate to the message</param> /// <param name="msg">the request message</param> /// <param name="asyncState">the asyncState relate to the message</param> public abstract Task PutRequestAsync(RequestContextBase context, Message msg, object asyncState);
/// <summary> /// Request received for this client /// </summary> /// <param name="requestContext">indicating the request context</param> /// <param name="requestMessage">indicating the request message</param> /// <param name="state">indicating the state</param> /// <remarks>this method is thread safe</remarks> public async Task RequestReceived(RequestContextBase requestContext, Message requestMessage, object state) { // in case the broker client itself is disposed try { // Only allow request come in in client connected state if (this.state == BrokerClientState.ClientConnected) { BrokerTracing.EtwTrace.LogFrontEndRequestReceived(this.sharedData.BrokerInfo.SessionId, this.clientId, Utility.GetMessageIdFromMessage(requestMessage)); // Make sure requests are from the same client instance. If not, discard messages from previous client instance int batchId = GetBatchId(requestMessage); BrokerTracing.TraceInfo("[BrokerClient] RequestReceived Client {0}: Batch {1}: Message {2}.", this.clientId, batchId, Utility.GetMessageIdFromMessage(requestMessage)); if (batchId > this.currentBatchId) { using (await this.asyncLockForDiscardRequests.WriterLockAsync()) { if (batchId > this.currentBatchId) { BrokerTracing.TraceWarning("[BrokerClient] New client instance id encountered: {0}. Will discard unflushed requests", batchId); this.observer.ReduceUncommittedCounter(this.queue.AllRequestsCount - this.queue.FlushedRequestsCount); this.queue.DiscardUnflushedRequests(); this.currentBatchId = batchId; this.batchIdChangedEvent.Set(); this.batchMessageIds.Clear(); } } } if (batchId == this.currentBatchId) { using (await this.asyncLockForDiscardRequests.ReaderLockAsync()) { if (batchId == this.currentBatchId) { Guid messageId = Utility.GetMessageIdFromMessage(requestMessage); if (this.batchMessageIds.TryAdd(messageId, batchId)) { await this.queue.PutRequestAsync(requestContext, requestMessage, state); this.observer.IncomingRequest(); } else { BrokerTracing.TraceWarning("[BrokerClient] Client {0}: discarded one duplicate request with instanceId: {1}, messageId {2}.", this.clientId, batchId, messageId); } } else { Debug.Assert( batchId < this.currentBatchId, string.Format("Unexpected clientInstanceId {0} and currentClientInstanceId {1}", batchId, this.currentBatchId)); Guid messageId = Utility.GetMessageIdFromMessage(requestMessage); BrokerTracing.TraceWarning("[BrokerClient] Client {0}: discarded one request with instanceId: {1}, messageId {2}.", this.clientId, batchId, messageId); } } } else { Debug.Assert( batchId < this.currentBatchId, string.Format("Unexpected clientInstanceId {0} and currentClientInstanceId {1}", batchId, this.currentBatchId)); Guid messageId = Utility.GetMessageIdFromMessage(requestMessage); BrokerTracing.TraceWarning("[BrokerClient] Client {0}: discarded one request with instanceId: {1}, messageId {2}.", this.clientId, batchId, messageId); } if (this.sharedData.BrokerInfo.Durable) { // Reset timeout for durable session, stop it when Flush succeeds which means there's outstanding reqeusts. this.timeoutManager.ResetTimeout(); } else { // Bug 4842: Stop timeout when there's outstanding requests for interactive session this.timeoutManager.Stop(); } } else { BrokerTracing.EtwTrace.LogFrontEndRequestRejectedClientStateInvalid(this.sharedData.BrokerInfo.SessionId, this.clientId, Utility.GetMessageIdFromMessage(requestMessage)); } } catch (NullReferenceException en) { BrokerTracing.TraceWarning("[BrokerClient] NullReferenceException is thrown for the broker client may be disposing: {0}", en); } catch (ObjectDisposedException eo) { BrokerTracing.TraceWarning("[BrokerClient] ObjectDisposedException is thrown for the broker client may be disposing: {0}", eo); } }
public RequestBase() { Context = new RequestContextBase(); }
public RequestBase() { Context = new RequestContextBase(); Messages = new List <string>(); }
public WorkItemRepositoryExposed(RequestContextBase context) { this.context = context; this.witClient = context.WitClient; }
/// <summary> /// Informs that a reply has been sent /// </summary> /// <param name="context">indicating the request context</param> /// <param name="isFault">indicating whether the reply is fault message</param> private void ReplySent(RequestContextBase context, bool isFault) { this.observer.ReplySent(isFault); context.CorrespondingBrokerClient.RegisterTimeoutIfNoPendingRequests(); }