public async Task <TResult> UpdateAsyncAsync <TData, TResult>(string rowKey, string partitionKey,
                                                                      UpdateDelegate <TData, Task <TResult> > onUpdate,
                                                                      Func <Task <TResult> > onNotFound = default(Func <Task <TResult> >),
                                                                      RetryDelegateAsync <Task <TResult> > onTimeoutAsync = default(RetryDelegateAsync <Task <TResult> >))
            where TData : class, ITableEntity
        {
            return(await await FindByIdAsync(rowKey, partitionKey,
                                             async (TData currentStorage) =>
            {
                var resultGlobal = default(TResult);
                var useResultGlobal = false;
                var resultLocal = await onUpdate.Invoke(currentStorage,
                                                        async(documentToSave) =>
                {
                    useResultGlobal = await await UpdateIfNotModifiedAsync(documentToSave,
                                                                           () => false.ToTask(),
                                                                           async() =>
                    {
                        if (onTimeoutAsync.IsDefaultOrNull())
                        {
                            onTimeoutAsync = GetRetryDelegateContentionAsync <Task <TResult> >();
                        }

                        resultGlobal = await await onTimeoutAsync(
                            async() => await UpdateAsyncAsync(rowKey, partitionKey, onUpdate, onNotFound, onTimeoutAsync),
                            (numberOfRetries) => { throw new Exception("Failed to gain atomic access to document after " + numberOfRetries + " attempts"); });
                        return true;
                    },
                                                                           onTimeout: GetRetryDelegate());
                });
                return useResultGlobal ? resultGlobal : resultLocal;
            },
                                             onNotFound,
Exemplo n.º 2
0
        public static async Task <T> RetryAsync <T>(this IRetryPolicy retryPolicy,
                                                    RetryDelegateAsync <T> callback,
                                                    Func <T> onFailureCallback,
                                                    int retryHttpStatus = 200, Exception retryException = default(Exception))
        {
            if (default(Exception) == retryException)
            {
                retryException = new Exception();
            }

            var      retriesAttempted = 0;
            TimeSpan retryDelay;
            var      result = default(T);

            while (retryPolicy.ShouldRetry(retriesAttempted++, retryHttpStatus, retryException, out retryDelay, null))
            {
                var unlockSucceeded = false;
                await callback((updatedResult) =>
                {
                    unlockSucceeded = true;
                    result          = updatedResult;
                });

                if (unlockSucceeded)
                {
                    return(result);
                }

                await Task.Delay(retryDelay);
            }
            return(onFailureCallback());
        }
 public Task <TResult> UpdateAsync <TData, TResult>(string rowKey, string partitionKey,
                                                    UpdateDelegate <TData, Task <TResult> > onUpdate,
                                                    Func <TResult> onNotFound = default(Func <TResult>),
                                                    RetryDelegateAsync <Task <TResult> > onTimeoutAsync = default(RetryDelegateAsync <Task <TResult> >))
     where TData : class, ITableEntity
 {
     return(UpdateAsyncAsync(rowKey, partitionKey, onUpdate, onNotFound.AsAsyncFunc(), onTimeoutAsync));
 }
        public async Task <TResult> UpdateAsync <TData, TResult>(Guid documentId, string partitionKey,
                                                                 UpdateDelegate <TData, Task <TResult> > onUpdate,
                                                                 Func <TResult> onNotFound = default(Func <TResult>),
                                                                 RetryDelegateAsync <Task <TResult> > onTimeoutAsync = default(RetryDelegateAsync <Task <TResult> >))
            where TData : class, ITableEntity
        {
            var rowKey = documentId.AsRowKey();

            return(await UpdateAsync(rowKey, partitionKey, onUpdate, onNotFound));
        }
        public async Task <TResult> UpdateAsyncAsync <TData, TResult>(Guid documentId,
                                                                      UpdateDelegate <TData, Task <TResult> > onUpdate,
                                                                      Func <Task <TResult> > onNotFound = default(Func <Task <TResult> >),
                                                                      RetryDelegateAsync <Task <TResult> > onTimeoutAsync = default(RetryDelegateAsync <Task <TResult> >),
                                                                      Func <string, string> mutatePartition = default(Func <string, string>))
            where TData : class, ITableEntity
        {
            var rowKey       = documentId.AsRowKey();
            var partitionKey = rowKey.GeneratePartitionKey();

            if (!mutatePartition.IsDefaultOrNull())
            {
                partitionKey = mutatePartition(partitionKey);
            }
            return(await UpdateAsyncAsync(rowKey, partitionKey, onUpdate, onNotFound));
        }
        public async Task <TResult> UpdateWithPartitionAsync <TData, TResult>(Guid documentId, string partitionKey,
                                                                              UpdateDelegate <TData, Task <TResult> > onUpdate,
                                                                              Func <TResult> onNotFound = default(Func <TResult>),
                                                                              RetryDelegateAsync <Task <TResult> > onTimeoutAsync = default(RetryDelegateAsync <Task <TResult> >),
                                                                              Func <string, string> mutatePartition = default(Func <string, string>))
            where TData : class, ITableEntity
        {
            if (partitionKey.IsNullOrWhiteSpace())
            {
                return(await UpdateAsync(documentId, onUpdate, onNotFound, onTimeoutAsync, mutatePartition));
            }

            var rowKey = documentId.AsRowKey();

            if (!mutatePartition.IsDefaultOrNull())
            {
                partitionKey = mutatePartition(partitionKey);
            }
            return(await UpdateAsync(rowKey, partitionKey, onUpdate, onNotFound));
        }