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); }
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)); }
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());