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

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

            var result = TryGetExisting(input);

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

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

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

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

            result.UseNew(context, usedBy);
            return(result);
        }
Beispiel #2
0
        public virtual async Task <TOut> InvokeAndStripAsync(TIn input,
                                                             IComputed?usedBy,
                                                             ComputeContext?context,
                                                             CancellationToken cancellationToken = default)
        {
            context ??= ComputeContext.Current;
            Result <TOut> output;

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

            var result = TryGetExisting(input);

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

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

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

            result = await ComputeAsync(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);
        }
        public override async Task <T> InvokeAndStripAsync(
            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.TryUseExistingAsync(context, usedBy, cancellationToken)
                         .ConfigureAwait(false);

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

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

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

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

            computed = (IAsyncComputed <T>) await ComputeAsync(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);
        }