示例#1
0
        protected virtual async Task <TResponseMessage> SendInternal <TResponseMessage>(IRequestMessage <TResponseMessage> request, TimeSpan?timeout, string topic, CancellationToken cancellationToken)
        {
            if (Settings.RequestResponse == null)
            {
                throw new PublishMessageBusException("An attempt to send request when request/response communication was not configured for the message bus. Ensure you configure the bus properly before the application starts.");
            }

            // check if the cancellation was already requested
            cancellationToken.ThrowIfCancellationRequested();

            var requestType       = request.GetType();
            var publisherSettings = GetPublisherSettings(requestType);

            if (topic == null)
            {
                topic = GetDefaultTopic(requestType, publisherSettings);
            }

            if (timeout == null)
            {
                timeout = GetDefaultRequestTimeout(requestType, publisherSettings);
            }

            var replyTo = Settings.RequestResponse.Topic;
            var created = CurrentTime;
            var expires = created.Add(timeout.Value);

            // generate the request guid
            var requestId      = GenerateRequestId();
            var requestPayload = SerializeRequest(requestType, request, requestId, replyTo, expires);

            // record the request state
            var requestState = new PendingRequestState(requestId, request, requestType, typeof(TResponseMessage), created, expires, cancellationToken);

            PendingRequestStore.Add(requestState);

            if (Log.IsTraceEnabled)
            {
                Log.TraceFormat("Added to PendingRequests, total is {0}", PendingRequestStore.GetCount());
            }

            try
            {
                Log.DebugFormat("Sending request message {0} to topic {1} with reply to {2} and payload size {3}", requestState, topic, replyTo, requestPayload.Length);
                await PublishToTransport(requestType, request, topic, requestPayload);
            }
            catch (PublishMessageBusException e)
            {
                Log.DebugFormat("Publishing of request message failed: {0}", e);
                // remove from registry
                PendingRequestStore.Remove(requestId);
                throw;
            }

            // convert Task<object> to Task<TResponseMessage>
            var typedTask = Convert <TResponseMessage>(requestState.TaskCompletionSource.Task);

            return(await typedTask);
        }
示例#2
0
        protected virtual void CleanPendingRequests(object sender, ElapsedEventArgs args)
        {
            var now = CurrentTime;

            var requestsToCancel = PendingRequestStore.FindAllToCancel(now);

            foreach (var requestState in requestsToCancel)
            {
                // request is either cancelled (via CancellationToken) or expired
                var canceled = requestState.CancellationToken.IsCancellationRequested
                    ? requestState.TaskCompletionSource.TrySetCanceled(requestState.CancellationToken)
                    : requestState.TaskCompletionSource.TrySetCanceled();

                if (PendingRequestStore.Remove(requestState.Id) && canceled)
                {
                    Log.DebugFormat("Pending request timed-out: {0}, now: {1}", requestState, now);
                    // ToDo: add and API hook to these kind of situation
                }
            }
        }
示例#3
0
        /// <summary>
        /// Performs cleanup of pending requests (requests that timed out or were cancelled).
        /// </summary>
        public virtual void CleanPendingRequests()
        {
            var now = CurrentTime;

            var requestsToCancel = PendingRequestStore.FindAllToCancel(now);

            foreach (var requestState in requestsToCancel)
            {
                // request is either cancelled (via CancellationToken) or expired
                var canceled = requestState.CancellationToken.IsCancellationRequested
                    ? requestState.TaskCompletionSource.TrySetCanceled(requestState.CancellationToken)
                    : requestState.TaskCompletionSource.TrySetCanceled();

                if (PendingRequestStore.Remove(requestState.Id) && canceled)
                {
                    Log.DebugFormat("Pending request timed-out: {0}, now: {1}", requestState, now);
                    // Execute the event hook
                    // ToDo: sort out the ConsumerSettings arg for req/resp, for now pass null
                    (Settings.RequestResponse.OnMessageExpired ?? Settings.OnMessageExpired)?.Invoke(null, requestState.Request);
                }
            }
        }