Beispiel #1
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

            var headers = response.Headers;

            if (headers.TryGetValues(FusionHeaders.Publication, out var values))
            {
                var header = values.FirstOrDefault();
                if (!string.IsNullOrEmpty(header))
                {
                    var psi = JsonConvert.DeserializeObject <PublicationStateInfo>(header);
                    if (response.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // Providing extended error info
                        var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                        var error = new ApiException(request, response, content);
                        psi = new PublicationStateInfo <object>(psi, Result.Error <object>(error));
                    }
                    PublicationStateInfoCapture.TryCapture(psi);
                }
            }
            return(response);
        }
Beispiel #2
0
        public override T Deserialize <T>(
            string?content, HttpResponseMessage response,
            ResponseDeserializerInfo info)
        {
            var headers = response.Headers;

            if (headers.TryGetValues(FusionHeaders.Publication, out var values))
            {
                var header = values.FirstOrDefault();
                if (!header.IsNullOrEmpty())
                {
                    var psi = JsonConvert.DeserializeObject <PublicationStateInfo>(header);
                    PublicationStateInfoCapture.Capture(psi);
                }
            }
            return(InnerDeserializer.Deserialize <T>(content, response, info));
        }
Beispiel #3
0
    protected override async ValueTask <IComputed <T> > Compute(
        ComputeMethodInput input, IComputed <T>?existing,
        CancellationToken cancellationToken)
    {
        var                       method = input.Method;
        IReplica <T>              replica;
        IReplicaComputed <T>      replicaComputed;
        ReplicaMethodComputed <T> result;

        // 1. Trying to update the Replica first
        if (existing is IReplicaMethodComputed <T> rsc && rsc.Replica != null)
        {
            try {
                replica         = rsc.Replica;
                replicaComputed = (IReplicaComputed <T>)
                                  await replica.Computed.Update(cancellationToken).ConfigureAwait(false);

                result = new (method.Options, input, replicaComputed);
                ComputeContext.Current.TryCapture(result);
                return(result);
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception e) {
                DebugLog?.LogError(e, "ComputeAsync: error on Replica update");
            }
        }

        // 2. Replica update failed, let's refresh it
        Result <T>           output;
        PublicationStateInfo?psi;

        using (var psiCapture = new PublicationStateInfoCapture()) {
            try {
                var rpcResult = input.InvokeOriginalFunction(cancellationToken);
                if (method.ReturnsValueTask)
                {
                    var task = (ValueTask <T>)rpcResult;
                    output = Result.Value(await task.ConfigureAwait(false));
                }
                else
                {
                    var task = (Task <T>)rpcResult;
                    output = Result.Value(await task.ConfigureAwait(false));
                }
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception e) {
                DebugLog?.LogError(e, "ComputeAsync: error on update");
                if (e is AggregateException ae)
                {
                    e = ae.GetFirstInnerException();
                }
                output = Result.Error <T>(e);
            }
            psi = psiCapture.Captured;
        }

        if (psi == null)
        {
            output = new Result <T>(default !, Errors.NoPublicationStateInfo());
        protected override async ValueTask <IComputed <T> > ComputeAsync(
            InterceptedInput input, IComputed <T>?existing,
            CancellationToken cancellationToken)
        {
            var                  method = input.Method;
            IReplica <T>         replica;
            IReplicaComputed <T> replicaComputed;

            // 1. Trying to update the Replica first
            if (existing is IReplicaClientComputed <T> rsc && rsc.Replica != null)
            {
                try {
                    replica         = rsc.Replica;
                    replicaComputed = (IReplicaComputed <T>) await replica.Computed
                                      .UpdateAsync(true, cancellationToken).ConfigureAwait(false);

                    return(new ReplicaClientComputed <T>(method.Options, input, replicaComputed));
                }
                catch (OperationCanceledException) {
                    if (IsLogDebugEnabled)
                    {
                        Log.LogDebug($"{nameof(ComputeAsync)}: Cancelled (1).");
                    }
                    throw;
                }
                catch (Exception e) {
                    if (IsLogDebugEnabled)
                    {
                        Log.LogError(e, $"{nameof(ComputeAsync)}: Error on Replica update.");
                    }
                }
            }

            // 2. Replica update failed, let's refresh it
            using var psiCapture = new PublicationStateInfoCapture();
            Result <T> output;

            try {
                var result = input.InvokeOriginalFunction(cancellationToken);
                if (method.ReturnsValueTask)
                {
                    var task = (ValueTask <T>)result;
                    output = Result.Value(await task.ConfigureAwait(false));
                }
                else
                {
                    var task = (Task <T>)result;
                    output = Result.Value(await task.ConfigureAwait(false));
                }
            }
            catch (OperationCanceledException) {
                if (IsLogDebugEnabled)
                {
                    Log.LogDebug($"{nameof(ComputeAsync)}: Cancelled (2).");
                }
                throw;
            }
            catch (Exception e) {
                if (IsLogDebugEnabled)
                {
                    Log.LogError(e, $"{nameof(ComputeAsync)}: Error on update.");
                }
                if (e is AggregateException ae)
                {
                    e = ae.GetFirstInnerException();
                }
                output = Result.Error <T>(e);
            }

            var psi = psiCapture.Captured;

            if (psi == null)
            {
                output = new Result <T>(default !, Errors.NoPublicationStateInfoCaptured());