Example #1
0
        public virtual async Task <T?> LoadAsync <T>(string key) where T : class
        {
            CheckKeyValid(key);

            var filePath = GetFilePathForKey(key);

            if (!File.Exists(filePath))
            {
                throw new Exception($"Load called on Yaml file that doesnt exist: {filePath}");
            }

            RegisterKnownKey(key);

            // see SaveAsync for why this is commented
            //using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize: 4096, useAsync: true);
            //var encodedData = new byte[stream.Length];
            //await stream.ReadAsync(encodedData, 0, (int)stream.Length);

            // Retry fixes stupid IOException ("File being used by another process")
            // when reading from a FileSystemWatcher's event.
            //
            // Similar: https://stackoverflow.com/q/49551278
            var encodedData = await Retry.DoAsync(() => File.ReadAllBytes((filePath)), TimeSpan.FromMilliseconds(1), 5);

            using var sha = new SHA256Managed();
            var contentHash = BitConverter.ToString(sha.ComputeHash(encodedData));

            m_ContentHash[key] = contentHash;

            var serializedYaml = Encoding.UTF8.GetString(encodedData);

            return(m_Deserializer.Deserialize <T>(serializedYaml));
        }
Example #2
0
        public override async Task <IExecutionResult <bool> > HandleAsync(CartCheckoutCommand command, CancellationToken cancellationToken)
        {
            if (!command.IsValid())
            {
                return(ValidationErrors(command));
            }

            var cart = await _cartRepository.GetById(command.Id.ToString());

            if (cart == null)
            {
                return(ExecutionError(command, ErrorMessages.Cart.DoesNotExistsById));
            }

            var items = cart.Items.Select(x => new CartItem(x.Id)
            {
                Price        = x.Price,
                Scale        = x.Scale,
                CurrencyCode = x.CurrencyCode,
                Product      = _productRepository.GetById(x.Id.ToString()).Result
            }).ToList();

            cart.Items = items;

            var invoice          = new Invoice(command.XTeamControl, command.CurrencyCode);
            var invoiceAggregate = new InvoiceAggregate(invoice, cart);

            await Retry.DoAsync(async() => await _queueService.SendToSqsAsync(invoiceAggregate));

            var result = await _cartRepository.Checkout(command.Id.ToString());

            return(new SuccessExecutionResult <bool>(GetType(), result));
        }
Example #3
0
        public void RetryAsync_CancellationToken_ShouldCancelUsingAsynchronousAction()
        {
            var       retriesPerformed  = 0;
            const int expectedRetries   = 2;
            const int maxRetries        = 5;
            var       cancellationToken = new CancellationTokenSource();

            // fail on all retries, but cancel on the second failure
            Assert.ThrowsAsync <RetryTimeoutException>(async() =>
            {
                await Retry.DoAsync(async() =>
                {
                    await Task.Delay(10);
                    retriesPerformed++;
                    throw new RetryTestException();
                }, TimeSpan.FromMilliseconds(10), maxRetries, cancellationToken.Token, async(ex, iteration, max) =>
                {
                    // await something
                    await Task.Delay(1);
                    if (iteration == expectedRetries - 1)
                    {
                        // cancel
                        cancellationToken.Cancel();
                    }
                });
            });

            // ensure we only retried twice and not the full maxRetries
            Assert.AreEqual(expectedRetries, retriesPerformed);
        }
Example #4
0
        public void RetryAsync_Static_ShouldRetryUntilEvaluatesToTrue()
        {
            // fail on all retries
            // this will ignore the maxRetries limit, if the evaluation parameters return false
            var       timeBetweenRetries = TimeSpan.FromMilliseconds(150);
            const int maxRetries         = 1;
            var       i = 0;

            Assert.ThrowsAsync <RetryTimeoutException>(async() =>
            {
                await Retry.DoAsync(async(iteration, max) =>
                {
                    await Task.Delay(10);
                    i++;
                    throw new RetryTestException();
                }, timeBetweenRetries,
                                    maxRetries,
                                    RetryPolicy.StaticDelay,
                                    RetryPolicyOptions.None,
                                    // don't need cancellation token
                                    null,
                                    // don't need an error handler
                                    null,
                                    // retry forever unless this evaluates to true (advanced usage)
                                    () => { return(i != 10); }
                                    );
            });
            Assert.AreEqual(10, i);
        }
Example #5
0
        public async Task Retry_Ok_Async()
        {
            object o1 = new object();
            async Task <object> act() => await Retry.DoAsync(async() => { return(await Task.FromResult(o1)); });

            Assert.Same(await act(), o1);
        }
Example #6
0
        public Task <T> ExecuteAsync <T>(IAsyncCommand <T> command, CancellationToken cancellationToken = default)
        {
            if (command.RequiresTransaction && _transaction == null)
            {
                throw new Exception($"The command {command.GetType()} requires a transaction");
            }

            return(Retry.DoAsync(() => command.ExecuteAsync(_connection, _transaction, cancellationToken), _retryOptions));
        }
Example #7
0
        public async Task RetrySucceedsOnSubsequentTryAsync()
        {
            _retries = 0;
            var completedDelegate = await Retry.DoAsync(
                async() => await SuccessOnSubsequentTry(1)
                , TimeSpan.FromSeconds(1));

            Debug.WriteLine(_retries.ToString());
            _retries.Should().BeGreaterThan(1);
        }
Example #8
0
        public async Task RetrySucceedsOnSubsequentTryAsync()
        {
            _retries = 0;
            var completedDelegate = await Retry.DoAsync(
                async() => await SuccessOnSubsequentTry(1)
                , TimeSpan.FromSeconds(1));

            Debug.WriteLine(_retries.ToString());
            Assert.IsTrue(_retries > 1);
        }
Example #9
0
        public async Task RetrySucceedsOnFirstTryAsync()
        {
            _retries = 0;

            var completedDelegate = await Retry.DoAsync(
                async() => await SucceedAlways(1)
                , TimeSpan.FromSeconds(1));

            Debug.WriteLine(_retries.ToString());
            _retries.Should().Be(1);
        }
Example #10
0
        public virtual async Task <CacheStream> DownloadAndCacheIfNeededAsync(string url, TaskParameter parameters, Configuration configuration, CancellationToken token)
        {
            var allowCustomKey = !string.IsNullOrWhiteSpace(parameters.CustomCacheKey) &&
                                 (string.IsNullOrWhiteSpace(parameters.LoadingPlaceholderPath) || parameters.LoadingPlaceholderPath != url) &&
                                 (string.IsNullOrWhiteSpace(parameters.ErrorPlaceholderPath) || parameters.ErrorPlaceholderPath != url);

            string filename         = (allowCustomKey ? MD5Helper.MD5(parameters.CustomCacheKey) : MD5Helper.MD5(url))?.ToSanitizedKey();
            var    allowDiskCaching = AllowDiskCaching(parameters.CacheType);
            var    duration         = parameters.CacheDuration.HasValue ? parameters.CacheDuration.Value : configuration.DiskCacheDuration;
            string filePath         = null;

            if (allowDiskCaching)
            {
                var diskStream = await configuration.DiskCache.TryGetStreamAsync(filename).ConfigureAwait(false);

                if (diskStream != null)
                {
                    token.ThrowIfCancellationRequested();
                    filePath = await configuration.DiskCache.GetFilePathAsync(filename).ConfigureAwait(false);

                    return(new CacheStream(diskStream, true, filePath));
                }
            }

            token.ThrowIfCancellationRequested();

            var downloadInfo = new DownloadInformation(url, parameters.CustomCacheKey, filename, allowDiskCaching, duration);

            parameters.OnDownloadStarted?.Invoke(downloadInfo);

            var responseBytes = await Retry.DoAsync(
                async() => await DownloadAsync(url, token, configuration.HttpClient).ConfigureAwait(false),
                DelayBetweenRetry,
                parameters.RetryCount,
                () => configuration.Logger.Debug(string.Format("Retry download: {0}", url)));

            if (responseBytes == null)
            {
                throw new HttpRequestException("No Content");
            }

            if (allowDiskCaching)
            {
                await configuration.DiskCache.AddToSavingQueueIfNotExistsAsync(filename, responseBytes, duration).ConfigureAwait(false);
            }

            token.ThrowIfCancellationRequested();
            filePath = await configuration.DiskCache.GetFilePathAsync(filename).ConfigureAwait(false);

            token.ThrowIfCancellationRequested();
            var memoryStream = new MemoryStream(responseBytes, false);

            return(new CacheStream(memoryStream, false, filePath));
        }
Example #11
0
        public async Task RetryFail()
        {
            _retries = 0;
            bool completedDelegate = await Retry.DoAsync(
                async() => await FailAlways()
                , TimeSpan.FromSeconds(1)
                , 3);

            Debug.WriteLine(_retries.ToString());
            Assert.IsTrue(_retries == 3);
        }
Example #12
0
        public async Task MakeAllFollowingsFollowersFollowRequestAsync(int top = 1000, IFilter <UserInfo> filter = null)
        {
            List <UserInfo> currentUserFollowingList = await instaService.GetCurrentUserFollowings();

            List <UserInfo> requestList = new List <UserInfo>();
            RandomGenerator random      = new RandomGenerator(currentUserFollowingList.Count);

            for (int i = 0; i < currentUserFollowingList.Count; i++)
            {
                int index     = random.Different();
                var following = currentUserFollowingList[index];
                logger.Write($"Random UserName : {following.UserName}, Index Order {i}");
                List <UserInfo> userInfoList = await instaService.GetUserFollowers(following.UserName, 10);

                filter = filter ?? FollowerFilter.DefaultFilter();


                var filtered = filter.Apply(userInfoList);
                filtered.RemoveAll(u => currentUserFollowingList.Exists(c => c.Id == u.Id));
                if (filtered != null && filtered.Count > 0)
                {
                    requestList.AddRange(filtered);
                }

                if (requestList.Count >= top)
                {
                    requestList = requestList.Take(top).ToList();
                    break;
                }
            }

            int requestIndex = 0;

            try
            {
                for (requestIndex = 0; requestIndex < requestList.Count; requestIndex++)
                {
                    logger.Write($"Requested UserName : {requestList[requestIndex].UserName}, Remaining User {requestList.Count - requestIndex - 1}");
                    await Retry.DoAsync(() => instaService.FollowUserAsync(requestList[requestIndex].Id), TimeSpan.FromSeconds(3));
                }
            }
            catch (Exception ex)
            {
                logger.Write(ex.ToString());
            }
            finally
            {
                if (requestIndex > 0)
                {
                    FileUtils.WriteAllToRequestedFile(requestList.Take(requestIndex).ToList());
                }
            }
        }
Example #13
0
        public async Task RetryFail()
        {
            _retries = 0;

            Func <Task <bool> > act = async() => await Retry.DoAsync(
                async() => await FailAlways()
                , TimeSpan.FromSeconds(1));

            await Assert.ThrowsAsync <AggregateException>(act);

            Debug.WriteLine(_retries.ToString());
            _retries.Should().Be(3);
        }
Example #14
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ctsToken)
        {
            using (await Util.AsyncLock.LockAsync().ConfigureAwait(false))
            {
                SocksConnection connection = null;
                try
                {
                    await Retry.DoAsync(() =>
                    {
                        connection = ConnectToDestinationIfNotConnected(request.RequestUri);
                    }, RetryInterval, MaxRetry).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    throw new TorException("Failed to connect to the destination", ex);
                }
                ctsToken.ThrowIfCancellationRequested();

                // https://tools.ietf.org/html/rfc7230#section-2.7.1
                // A sender MUST NOT generate an "http" URI with an empty host identifier.
                if (request.RequestUri.DnsSafeHost == "")
                {
                    throw new HttpRequestException("Host identifier is empty");
                }

                // https://tools.ietf.org/html/rfc7230#section-2.6
                // Intermediaries that process HTTP messages (i.e., all intermediaries
                // other than those acting as tunnels) MUST send their own HTTP - version
                // in forwarded messages.
                request.Version = Protocol.Version;

                try
                {
                    return(await connection.SendRequestAsync(request, ctsToken).ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    if (ex is OperationCanceledException)
                    {
                        throw;
                    }
                    else
                    {
                        throw new TorException("Failed to send the request", ex);
                    }
                }
            }
        }
Example #15
0
        public void RetryAsync_Static_ShouldRetryIntervalElapsed()
        {
            // fail on all retries
            var startTime          = DateTime.Now;
            var timeBetweenRetries = TimeSpan.FromMilliseconds(150);

            Assert.ThrowsAsync <RetryTimeoutException>(async() =>
            {
                await Retry.DoAsync(async() =>
                {
                    await Task.Delay(10);
                    throw new RetryTestException();
                }, timeBetweenRetries, 1, RetryPolicy.StaticDelay);
            });
            Assert.Greater(DateTime.Now.Subtract(startTime), timeBetweenRetries);
        }
Example #16
0
        private async Task <ImageAnalysisResult> GetImageAnalysisAsync(byte[] bytes)
        {
            ImageAnalysisResult result = null;

            try
            {
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", CoreConstants.ComputerVisionApiSubscriptionKey);

                    var payload = new ByteArrayContent(bytes);

                    payload.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                    var analysisFeatures = "Color,ImageType,Tags,Categories,Description,Adult,Faces";

                    var uri = new Uri($"{CoreConstants.CognitiveServicesBaseUrl}/vision/v1.0/analyze?visualFeatures={analysisFeatures}");

                    using (var results = await Retry.DoAsync(() => client.PostAsync(uri, payload), new TimeSpan(0, 0, 3), 10))
                    {
                        var analysisResults = await results.Content.ReadAsStringAsync();

                        var imageAnalysisResult = JsonConvert.DeserializeObject <ImageAnalysisInfo>(analysisResults);

                        result = new ImageAnalysisResult
                        {
                            id      = Guid.NewGuid().ToString(),
                            details = imageAnalysisResult,
                            caption = imageAnalysisResult.description.captions.FirstOrDefault()?.text,
                            tags    = imageAnalysisResult.description.tags.ToList()
                        };

                        if (string.IsNullOrEmpty(result.caption))
                        {
                            result.caption = "No caption";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"ComputerVisionService.GetImageAnalysisAsync Exception: {ex}");
            }

            return(result);
        }
Example #17
0
        public void RetryAsync_Static_ShouldRetryUntilMax()
        {
            var       retriesPerformed = 0;
            const int maxRetries       = 5;

            // fail on all retries
            Assert.ThrowsAsync <RetryTimeoutException>(async() =>
            {
                await Retry.DoAsync(async() =>
                {
                    await Task.Delay(10);
                    retriesPerformed++;
                    throw new RetryTestException();
                }, TimeSpan.FromMilliseconds(10), maxRetries);
            }
                                                       );
            Assert.AreEqual(5, retriesPerformed);
        }
Example #18
0
        public virtual async Task <Stream> DownloadAndCacheIfNeededAsync(string url, ILoadableImageSource imageSource, CancellationToken token)
        {
            string     filename         = MD5Helper.MD5(url);
            bool       allowDiskCaching = AllowDiskCaching(_imageLoader.CacheType);
            IDiskCache?diskCache        = _imageLoader.DiskCache;
            TimeSpan   duration         = _imageLoader.DiskCacheDuration;

            if (allowDiskCaching)
            {
                Stream?diskStream = await diskCache !.TryGetStreamAsync(filename).ConfigureAwait(false);
                token.ThrowIfCancellationRequested();

                if (diskStream != null)
                {
                    return(diskStream);
                }
            }

            var downloadInfo = new DownloadInformation(duration);

#if LATER
            parameters.OnDownloadStarted?.Invoke(downloadInfo);
#endif

            byte[] responseBytes = await Retry.DoAsync(
                async() => await DownloadAsync(url, token, _imageLoader.HttpClient, imageSource, downloadInfo).ConfigureAwait(false),
                TimeSpan.FromMilliseconds(_imageLoader.RetryDelayInMs),
                _imageLoader.RetryCount,
                () => _imageLoader.Logger?.Debug($"Retry download: {url}")).ConfigureAwait(false);

            if (responseBytes == null)
            {
                throw new HttpRequestException("No Content");
            }

            if (allowDiskCaching)
            {
                await diskCache !.AddToSavingQueueIfNotExistsAsync(filename, responseBytes, downloadInfo.CacheValidity).ConfigureAwait(false);
            }

            token.ThrowIfCancellationRequested();

            return(new MemoryStream(responseBytes, false));
        }
Example #19
0
        private async Task ChangeEventHandler(FileSystemEventArgs a)
        {
            if (a.ChangeType == WatcherChangeTypes.Renamed ||
                a.ChangeType == WatcherChangeTypes.Deleted)
            {
                return;
            }

            foreach (var key in m_KnownKeys)
            {
                var filePath = GetFilePathForKey(key);

                if (!a.FullPath.Equals(Path.GetFullPath(filePath), StringComparison.Ordinal))
                {
                    continue;
                }

                using var sha = new SHA256Managed();
                var encodedData = await Retry.DoAsync(
                    () => File.ReadAllBytes(filePath),
                    retryInterval : TimeSpan.FromMilliseconds(1),
                    maxAttempts : 5);

                var fileHash = BitConverter.ToString(sha.ComputeHash(encodedData));

                if (string.Equals(m_ContentHash[key], fileHash, StringComparison.Ordinal))
                {
                    // Nothing changed
                    return;
                }

                lock (GetLock(key))
                {
                    if (DecrementWriteCounter(key))
                    {
                        m_Logger?.LogDebug($"File changed: {a.FullPath} ({a.ChangeType:X})");
                        OnFileChange(key);
                    }
                }

                return;
            }
        }
Example #20
0
        public void RetryAsync_Static_ShouldRetryOnlyOnSpecifiedExceptions()
        {
            var       timeBetweenRetries = TimeSpan.FromMilliseconds(150);
            const int maxRetries         = 1;

            // we are only listening for RetryTestExceptions
            // if any other type of exception is thrown, it will be rethrown and no retry is performed
            Assert.ThrowsAsync <InvalidOperationException>(async() =>
            {
                await Retry.DoAsync(async(iteration, max) =>
                {
                    await Task.Delay(10);
                    throw new InvalidOperationException();
                }, timeBetweenRetries,
                                    maxRetries,
                                    // indicate we only want to catch RetryTestExceptions
                                    typeof(RetryTestException)
                                    );
            });
        }
Example #21
0
        public async Task Retry_Attempts_Zero_Throws_Async()
        {
            async Task act() => await Retry.DoAsync(async() => { await Task.Run(() => { }); }, null, 0);

            await Assert.ThrowsAsync <ArgumentOutOfRangeException>(act);
        }
Example #22
0
        public async Task Retry_Interval_Zero_Throws_Async()
        {
            async Task act() => await Retry.DoAsync(async() => { await Task.Run(() => { }); }, TimeSpan.FromSeconds(0));

            await Assert.ThrowsAsync <ArgumentOutOfRangeException>(act);
        }
Example #23
0
 public Task <T> QueryAsync <T>(IAsyncQuery <T> query, CancellationToken cancellationToken = default)
 => Retry.DoAsync(() => query.ExecuteAsync(_connection, _transaction, cancellationToken), _retryOptions);