コード例 #1
0
        public async Task <Result <bool> > CompareExchangeAsync(
            OperationContext context,
            StrongFingerprint strongFingerprint,
            SerializedMetadataEntry replacement,
            string expectedReplacementToken)
        {
            var key = GetKey(strongFingerprint.WeakFingerprint);
            var replacementBytes = replacement.Data;

            byte[] selectorBytes       = SerializeSelector(strongFingerprint.Selector, isReplacementToken: false);
            byte[] tokenFieldNameBytes = SerializeSelector(strongFingerprint.Selector, isReplacementToken: true);

            var(primaryResult, secondaryResult) = await _redis.ExecuteRaidedAsync <bool>(
                context,
                async (redis, cancellationToken) =>
            {
                using var nestedContext = new CancellableOperationContext(context, cancellationToken);

                return(await redis.ExecuteBatchAsync(
                           nestedContext,
                           batch =>
                {
                    var task = batch.CompareExchangeAsync(
                        key,
                        selectorBytes,
                        tokenFieldNameBytes,
                        expectedReplacementToken,
                        replacementBytes,
                        replacement.ReplacementToken);
                    batch.KeyExpireAsync(key, Configuration.ExpiryTime).FireAndForget(nestedContext);
                    return task;
                },
                           RedisOperation.CompareExchange));
            },
                retryWindow : Configuration.SlowOperationCancellationTimeout);

            Contract.Assert(primaryResult != null || secondaryResult != null);

            if (primaryResult?.Succeeded == true || secondaryResult?.Succeeded == true)
            {
                // One of the operations is successful.
                return((primaryResult?.Value ?? false) || (secondaryResult?.Value ?? false));
            }

            // All operations failed, propagating the error back to the caller.
            var failure = primaryResult ?? secondaryResult;

            Contract.Assert(!failure.Succeeded);
            return(new Result <bool>(failure));
        }
コード例 #2
0
        public Task <Result <bool> > CompareExchangeAsync(
            OperationContext context,
            StrongFingerprint strongFingerprint,
            SerializedMetadataEntry replacement,
            string expectedReplacementToken)
        {
            var result = Database.CompareExchange(
                context,
                strongFingerprint,
                replacement,
                expectedReplacementToken,
                null).ToResult();

            return(Task.FromResult(result));
        }
コード例 #3
0
        public Task <Result <bool> > CompareExchangeAsync(
            OperationContext context,
            StrongFingerprint strongFingerprint,
            SerializedMetadataEntry replacement,
            string expectedReplacementToken)
        {
            return(ExecuteAsync(context, async(context, callOptions, service) =>
            {
                var response = await service.CompareExchangeAsync(new CompareExchangeRequest()
                {
                    StrongFingerprint = strongFingerprint,
                    Replacement = replacement,
                    ExpectedReplacementToken = expectedReplacementToken
                }, callOptions);

                return response.ToResult(r => r.Exchanged);
            },
                                extraEndMessage: r => $"Exchanged=[{r.GetValueOrDefault()}]"));
        }
コード例 #4
0
 public Task <Result <bool> > CompareExchangeAsync(OperationContext context, StrongFingerprint strongFingerprint, SerializedMetadataEntry replacement, string expectedReplacementToken)
 {
     return(WriteAsync(context, MemoizationMode, store => store.CompareExchangeAsync(context, strongFingerprint, replacement, expectedReplacementToken)));
 }