示例#1
0
        public AmqpRequestOptions Parse(AmqpRequestOptions options, IDictionary <string, object> properties)
        {
            if (properties == null)
            {
                return(options);
            }

            if (properties.TryGetValue(nameof(options.Timeout).ToLower(), out var timeoutProperties))
            {
                if (int.TryParse(timeoutProperties as string, out var timeout))
                {
                    options.Timeout = timeout;
                }
                else
                {
                    _log.LogWarning("Timeout Header exists in request properties. but not int value (count seconds)");
                }
            }

            if (properties.TryGetValue(nameof(options.CallType).ToLower(), out var callTypeProperies))
            {
                if (callTypeProperies is AmqpCallType callType ||
                    Enum.TryParse(callTypeProperies as string, true, out callType))
                {
                    options.CallType = callType;
                }
                else
                {
                    _log.LogWarning("Timeout Header exists in request properties. but not int value (count seconds)");
                }
            }
示例#2
0
        public async Task <HttpResponseMessage> Send(Uri baseUri, HttpRequestMessage request,
                                                     AmqpRequestOptions options)
        {
            CheckParams(baseUri, request);

            if (options == null)
            {
                options = AmqpRequestOptions.DefaultOptions;
            }

            var response = new AmqpResponse
            {
                RequestOptions = options
            };

            var cancellationToken = new CancellationToken();

            var cancellationTokenSource =
                CancellationTokenSource.CreateLinkedTokenSource(options.CancellationToken, cancellationToken);

            var competionSource = response.Response;

            if (options.CallType == AmqpCallType.Rpc && options.Timeout == 0)
            {
                options.Timeout = AmqpCommunication.RPC_TIMEOUT;
                _log.LogWarning(
                    $"Call {AmqpCommunication.ProtocolName} by type {options.CallType} must be expired time. Set default value {options.Timeout}");
            }

            var correlationId = request.Headers.GetCorrelationHeader();

            if (!string.IsNullOrWhiteSpace(correlationId))
            {
                if (options.CallType == AmqpCallType.Call)
                {
                    options.Timeout = AmqpCommunication.Call_TIMEOUT;
                    _log.LogInformation(
                        $"Identifier callback set in headers. But calltype {options.CallType}. This type specified not sent response. Response will cached by {options.Timeout} CorrelationId {correlationId}.");
                }

                _callbacks.Set(correlationId, response, options.Expires);
            }

            try
            {
                await _client.Send(baseUri, request, options);

                if (options.CallType == AmqpCallType.Call)
                {
                    _log.LogTrace(
                        $"Call type {options.CallType}. Server not sent ansewer. Default http status set 200.");
                    response.Response.SetResult(new HttpResponseMessage(HttpStatusCode.OK));
                    response.EndTiming(TaskStatus.RanToCompletion);
                }
            }
            catch (Exception e)
            {
                cancellationTokenSource.Cancel();
                _log.LogError(e, "Request send error");
                competionSource.SetException(new Exception($"no sent request to resource {baseUri} {request.RequestUri}",
                                                           e));
                response.EndTiming(TaskStatus.Faulted);
                response.Exception = e;

                return(await competionSource.Task);
            }

            await Task.WhenAny(competionSource.Task, Task.Delay(options.Expires, cancellationTokenSource.Token));

            if (!competionSource.Task.IsCompleted)
            {
                response.EndTiming(TaskStatus.Canceled);
                competionSource.SetCanceled();
            }

            return(await competionSource.Task);
        }