Ejemplo n.º 1
0
        /// <inheritdoc />
        public virtual async Task <TResponse> RequestAsync <TRequest, TResponse>(
            TRequest request,
            Action <IRequestConfiguration> configure,
            CancellationToken cancellationToken = default
            )
        {
            Preconditions.CheckNotNull(request, "request");

            var requestType          = typeof(TRequest);
            var requestConfiguration = new RequestConfiguration(
                conventions.RpcRoutingKeyNamingConvention(requestType),
                configuration.Timeout
                );

            configure(requestConfiguration);

            using var cts = cancellationToken.WithTimeout(requestConfiguration.Expiration);

            var correlationId = correlationIdGenerationStrategy.GetCorrelationId();
            var tcs           = new TaskCompletionSource <TResponse>(TaskCreationOptions.RunContinuationsAsynchronously);

            RegisterResponseActions(correlationId, tcs);
            using var callback = DisposableAction.Create(DeRegisterResponseActions, correlationId);

            var queueName = await SubscribeToResponseAsync <TRequest, TResponse>(cts.Token).ConfigureAwait(false);

            var routingKey = requestConfiguration.QueueName;
            var expiration = requestConfiguration.Expiration;
            var priority   = requestConfiguration.Priority;

            await RequestPublishAsync(
                request, routingKey, queueName, correlationId, expiration, priority, configuration.MandatoryPublish, cts.Token
                ).ConfigureAwait(false);

            tcs.AttachCancellation(cts.Token);
            return(await tcs.Task.ConfigureAwait(false));
        }