// Two primary constructors public ReplicaClientComputed(ComputedOptions options, InterceptedInput input, IReplicaComputed <T> source) : this(source.Replica, options, input, source.Version) { ((IComputedImpl)this).AddUsed((IComputedImpl)source); TrySetOutput(source.Output); if (!source.IsConsistent()) { Invalidate(); } }
public override IComputed <T>?TryGetCached(InterceptedInput input) { if (!(ComputedRegistry.TryGet(input) is IReplicaClientComputed <T> computed)) { return(null); } var replica = computed.Replica; if (replica == null || replica.UpdateError != null || replica.DisposalState != DisposalState.Active) { ComputedRegistry.Remove(computed); return(null); } return(computed); }
public override IComputed <T>?TryGetCached(InterceptedInput input, IComputed?usedBy) { if (!(ComputedRegistry.TryGet(input) is IReplicaServiceComputed <T> computed)) { return(null); } var replica = computed.Replica; if (replica == null || replica.UpdateError != null || replica.DisposalState != DisposalState.Active) { ComputedRegistry.Remove(computed); return(null); } ((IComputedImpl?)usedBy)?.AddUsed((IComputedImpl)computed); return(computed); }
protected SwappingComputed(ComputedOptions options, InterceptedInput input, ResultBox <T> maybeOutput, LTag version, bool isConsistent) : base(options, input, default, version, isConsistent) => _maybeOutput = maybeOutput;
public SwappingComputed(ComputedOptions options, InterceptedInput input, LTag version) : base(options, input, version) { }
public ReplicaClientComputed(ComputedOptions options, InterceptedInput input, Exception error, LTag version) : this(options, null, input, new Result <T>(default !, error), version, false)
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());
public ReplicaServiceComputed(ComputedOptions options, InterceptedInput input, Exception error, LTag lTag) : this(options, null, input, new Result <T>(default !, error), lTag, false)
// Two primary constructors public ReplicaServiceComputed(ComputedOptions options, IReplicaComputed <T> source, InterceptedInput input) : this(options, source.Replica, input, source.LTag) { ((IComputedImpl)this).AddUsed((IComputedImpl)source); TrySetOutput(source.Output); if (!source.IsConsistent) { Invalidate(); } }
protected override async ValueTask <IComputed <T> > ComputeAsync( InterceptedInput input, IComputed <T>?cached, CancellationToken cancellationToken) { var method = input.Method; // 1. Trying to update the Replica first if (cached is IReplicaServiceComputed <T> rsc && rsc.Replica != null) { try { var replica = rsc.Replica; var computed = await replica.Computed .UpdateAsync(true, cancellationToken).ConfigureAwait(false); var replicaComputed = (IReplicaComputed <T>)computed; var output = new ReplicaServiceComputed <T>( method.Options, replicaComputed, input); return(output); } 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 try { using var replicaCapture = new ReplicaCapture(); var result = input.InvokeOriginalFunction(cancellationToken); if (method.ReturnsComputed) { if (method.ReturnsValueTask) { var task = (ValueTask <IComputed <T> >)result; await task.ConfigureAwait(false); } else { var task = (Task <IComputed <T> >)result; await task.ConfigureAwait(false); } } else { if (method.ReturnsValueTask) { var task = (ValueTask <T>)result; await task.ConfigureAwait(false); } else { var task = (Task <T>)result; await task.ConfigureAwait(false); } } var replica = replicaCapture.GetCapturedReplica <T>(); var computed = await replica.Computed .UpdateAsync(true, cancellationToken).ConfigureAwait(false); var replicaComputed = (IReplicaComputed <T>)computed; var output = new ReplicaServiceComputed <T>( method.Options, replicaComputed, input); return(output); } catch (OperationCanceledException) { if (_isLogDebugEnabled) { _log.LogDebug($"{nameof(ComputeAsync)}: Cancelled (2)."); } throw; } catch (Exception e) { if (_isLogDebugEnabled) { _log.LogError(e, $"{nameof(ComputeAsync)}: Error on update."); } // We need a unique LTag here, so we use a range that's supposed // to be unused by LTagGenerators. var lTag = new LTag(LTagGenerator.Next().Value ^ (1L << 62)); var output = new ReplicaServiceComputed <T>( method.Options, null, input, new Result <T>(default !, e), lTag);
protected Computed(ComputedOptions options, InterceptedInput input, Result <T> output, LTag version, bool isConsistent = true) : base(options, input, output, version, isConsistent) { }