Beispiel #1
0
    public virtual async Task <TOut> InvokeAndStrip(TIn input,
                                                    IComputed?usedBy,
                                                    ComputeContext?context,
                                                    CancellationToken cancellationToken = default)
    {
        context ??= ComputeContext.Current;
        Result <TOut> output;

        // Read-Lock-RetryRead-Compute-Store pattern

        var result = GetExisting(input);

        if (result.TryUseExisting(context, usedBy))
        {
            return(result.Strip(context));
        }

        using var @lock = await Locks.Lock(input, cancellationToken).ConfigureAwait(false);

        result = GetExisting(input);
        if (result.TryUseExisting(context, usedBy))
        {
            return(result.Strip(context));
        }

        result = await Compute(input, result, cancellationToken).ConfigureAwait(false);

        output = result.Output; // It can't be gone here b/c KeepAlive isn't called yet
        result.UseNew(context, usedBy);
        return(output.Value);
    }
Beispiel #2
0
    public virtual async Task <IComputed <TOut> > Invoke(TIn input,
                                                         IComputed?usedBy,
                                                         ComputeContext?context,
                                                         CancellationToken cancellationToken = default)
    {
        context ??= ComputeContext.Current;

        // Read-Lock-RetryRead-Compute-Store pattern

        var result = GetExisting(input);

        if (result.TryUseExisting(context, usedBy))
        {
            return(result !);
        }

        using var @lock = await Locks.Lock(input, cancellationToken).ConfigureAwait(false);

        result = GetExisting(input);
        if (result.TryUseExisting(context, usedBy))
        {
            return(result !);
        }

        result = await Compute(input, result, cancellationToken).ConfigureAwait(false);

        result.UseNew(context, usedBy);
        return(result);
    }
Beispiel #3
0
        public override async Task <T> InvokeAndStrip(
            ComputeMethodInput input, IComputed?usedBy, ComputeContext?context,
            CancellationToken cancellationToken = default)
        {
            context ??= ComputeContext.Current;
            ResultBox <T>?output;

            // Read-Lock-RetryRead-Compute-Store pattern

            var computed = TryGetExisting(input);

            if (computed != null)
            {
                output = await computed.TryUseExisting(context, usedBy, cancellationToken)
                         .ConfigureAwait(false);

                if (output != null)
                {
                    return(output.Value);
                }
            }

            using var @lock = await Locks.Lock(input, cancellationToken).ConfigureAwait(false);

            computed = TryGetExisting(input);
            if (computed != null)
            {
                output = await computed.TryUseExisting(context, usedBy, cancellationToken)
                         .ConfigureAwait(false);

                if (output != null)
                {
                    return(output.Value);
                }
            }

            computed = (IAsyncComputed <T>) await Compute(input, computed, cancellationToken)
                       .ConfigureAwait(false);

            var rOutput = computed.Output; // RenewTimeouts isn't called yet, so it's ok

            computed.UseNew(context, usedBy);
            return(rOutput !.Value);
        }