Exemplo n.º 1
0
        internal void RemoveFromTracker(
            [DefaultValue((uint)7089), Description("GRPC port")] uint grpcPort)
        {
            Initialize();

            // We need to initialize this here because there's no codepath otherwise.
            GrpcEnvironment.Initialize();

            var context     = new Context(_logger);
            var retryPolicy = RetryPolicyFactory.GetLinearPolicy(ex => ex is ClientCanRetryException, (int)_retryCount, TimeSpan.FromSeconds(_retryIntervalSeconds));

            _logger.Debug("Begin repair handling...");

            // This action is synchronous to make sure the calling application doesn't exit before the method returns.
            using (var rpcClient = new GrpcRepairClient(grpcPort))
            {
                var removeFromTrackerResult = retryPolicy.ExecuteAsync(() => rpcClient.RemoveFromTrackerAsync(context), _cancellationToken).Result;
                if (!removeFromTrackerResult.Succeeded)
                {
                    throw new CacheException(removeFromTrackerResult.ErrorMessage);
                }
                else
                {
                    _logger.Debug($"Repair handling succeeded. Removed {removeFromTrackerResult.Data} hashes from the content tracker.");
                }

                var shutdownResult = rpcClient.ShutdownAsync(context).Result;
                if (!shutdownResult.Succeeded)
                {
                    throw new CacheException(shutdownResult.ErrorMessage);
                }
            }
        }
        public async Task TestTracingRetryPolicy()
        {
            var context = new OperationContext(new Context(TestGlobal.Logger));

            const int RetryCount = 3;

            var retryPolicy = RetryPolicyFactory.GetLinearPolicy(shouldRetry: _ => true, retries: RetryCount, retryInterval: TimeSpan.FromMilliseconds(1));

            int callBackCallCount = 0;

            try
            {
                await retryPolicy.ExecuteAsync(
                    context.TracingContext,
                    async() =>
                {
                    callBackCallCount++;
                    await Task.Yield();
                    throw new ApplicationException("1");
                },
                    CancellationToken.None,
                    databaseName : string.Empty);

                Assert.True(false, "ExecuteAsync should fail.");
            }
            catch (ApplicationException)
            {
                var fullOutput = GetFullOutput();
                fullOutput.Should().Contain($"Redis operation '{nameof(TestTracingRetryPolicy)}' failed");
                callBackCallCount.Should().Be(RetryCount + 1); // +1 because we have: original try + the number of retries.
            }
        }
Exemplo n.º 3
0
        public async Task Test(bool usePolly)
        {
            RetryPolicyFactory.UsePolly = usePolly;
            var policy = RetryPolicyFactory.GetLinearPolicy(shouldRetry: _ => true, retries: 3, retryInterval: TimeSpan.FromMilliseconds(1));
            var c      = 0;

            (await policy.ExecuteAsync(() => c++ == 3 ? Task.FromResult(true) : throw new Exception(), CancellationToken.None)).Should().BeTrue();
        }
Exemplo n.º 4
0
        internal void CopyFile(
            [Required, Description("Machine to copy from")] string host,
            [Required, Description("Expected content hash")] string hashString,
            [Required, Description("Path to destination file")] string destinationPath,
            [Description("Whether or not GZip is enabled"), DefaultValue(false)] bool useCompressionForCopies,
            [Description("File name where the GRPC port can be found when using cache service. 'CASaaS GRPC port' if not specified")] string grpcPortFileName,
            [Description("The GRPC port"), DefaultValue(0)] int grpcPort)
        {
            Initialize();

            var context = new Context(_logger);

            var retryPolicy = RetryPolicyFactory.GetLinearPolicy(ex => ex is ClientCanRetryException, (int)_retryCount, TimeSpan.FromSeconds(_retryIntervalSeconds));

            if (grpcPort == 0)
            {
                grpcPort = Helpers.GetGrpcPortFromFile(_logger, grpcPortFileName);
            }

            if (!ContentHash.TryParse(hashString, out var hash))
            {
                throw new CacheException($"Invalid content hash string provided: {hashString}");
            }

            try
            {
                var config = new GrpcCopyClientConfiguration();
                using var clientCache = new GrpcCopyClientCache(context, new GrpcCopyClientCacheConfiguration()
                {
                    GrpcCopyClientConfiguration = config
                });

                var finalPath = new AbsolutePath(destinationPath);

                var copyFileResult = clientCache.UseAsync(new OperationContext(context), host, grpcPort, (nestedContext, rpcClient) =>
                {
                    return(retryPolicy.ExecuteAsync(
                               () => rpcClient.CopyFileAsync(nestedContext, hash, finalPath, new CopyOptions(bandwidthConfiguration: null)
                    {
                        CompressionHint = useCompressionForCopies ? CopyCompression.Gzip : CopyCompression.None,
                    }),
                               _cancellationToken));
                }).GetAwaiter().GetResult();

                if (!copyFileResult.Succeeded)
                {
                    throw new CacheException(copyFileResult.ErrorMessage);
                }
                else
                {
                    _logger.Debug($"Copy of {hashString} to {finalPath} was successful");
                }
            }
            catch (Exception ex)
            {
                throw new CacheException(ex.ToString());
            }
        }
Exemplo n.º 5
0
        internal void CopyFileTo(
            [Required, Description("Machine to copy to")] string host,
            [Required, Description("Path to source file")] string sourcePath,
            [Description("File name where the GRPC port can be found when using cache service. 'CASaaS GRPC port' if not specified")] string grpcPortFileName,
            [Description("The GRPC port"), DefaultValue(0)] int grpcPort)
        {
            Initialize();

            var context          = new Context(_logger);
            var operationContext = new OperationContext(context, CancellationToken.None);
            var retryPolicy      = RetryPolicyFactory.GetLinearPolicy(ex => ex is ClientCanRetryException, (int)_retryCount, TimeSpan.FromSeconds(_retryIntervalSeconds));

            if (grpcPort == 0)
            {
                grpcPort = Helpers.GetGrpcPortFromFile(_logger, grpcPortFileName);
            }

            var hasher = ContentHashers.Get(HashType.MD5);
            var bytes  = File.ReadAllBytes(sourcePath);
            var hash   = hasher.GetContentHash(bytes);

            try
            {
                var path = new AbsolutePath(sourcePath);
                using Stream stream = File.OpenRead(path.Path);

                var config = GrpcCopyClientConfiguration.WithGzipCompression(false);
                config.BandwidthCheckerConfiguration = BandwidthChecker.Configuration.Disabled;
                using var clientCache = new GrpcCopyClientCache(context, new GrpcCopyClientCacheConfiguration()
                {
                    GrpcCopyClientConfiguration = config
                });

                var copyFileResult = clientCache.UseAsync(operationContext, host, grpcPort, (nestedContext, rpcClient) =>
                {
                    return(retryPolicy.ExecuteAsync(
                               () => rpcClient.PushFileAsync(nestedContext, hash, stream, new CopyOptions(bandwidthConfiguration: null)),
                               _cancellationToken));
                }).GetAwaiter().GetResult();

                if (!copyFileResult.Succeeded)
                {
                    _tracer.Error(context, $"{copyFileResult}");
                    throw new CacheException(copyFileResult.ErrorMessage);
                }
                else
                {
                    _tracer.Info(context, $"Copy of {sourcePath} was successful");
                }
            }
            catch (Exception ex)
            {
                throw new CacheException(ex.ToString());
            }
        }
Exemplo n.º 6
0
        public async Task RetryPolicyStopsOnCancellation(bool usePolly)
        {
            RetryPolicyFactory.UsePolly = usePolly;

            // This test shows that if a cancellation token provided to 'RetryPolicy' is triggered
            // and at least one error already occurred, then the operation will fail with the last exception
            // If using Polly, TaskCancelledException is thrown.

            var cts     = new CancellationTokenSource();
            var context = new OperationContext(new Context(TestGlobal.Logger), cts.Token);

            const int RetryCount = 4;

            var retryPolicy = RetryPolicyFactory.GetLinearPolicy(shouldRetry: _ => true, retries: RetryCount, retryInterval: TimeSpan.FromMilliseconds(1));

            int callBackCallCount = 0;

            try
            {
                await retryPolicy.ExecuteAsync(
                    context.TracingContext,
                    async() =>
                {
                    callBackCallCount++;

                    if (callBackCallCount == 2)
                    {
                        cts.Cancel();
                    }
                    await Task.Yield();
                    throw new ApplicationException($"{callBackCallCount}");
                },
                    context.Token,
                    databaseName : string.Empty);

                Assert.True(false, "ExecuteAsync should fail.");
            }
            catch (ApplicationException e)
            {
                usePolly.Should().BeFalse();
                callBackCallCount.Should().Be(2);
                e.Message.Should().Be("2");
            }
            catch (TaskCanceledException)
            {
                usePolly.Should().BeTrue();
                callBackCallCount.Should().Be(2);
            }
        }
        public IRetryPolicy CreateRetryPolicy(Action <Exception> onRedisException)
        {
            var policy = new RedisDatabaseAdapter.RedisRetryPolicy(onRedisException, TreatObjectDisposedExceptionAsTransient);

            if (_retryCount != null)
            {
                return(RetryPolicyFactory.GetLinearPolicy(policy.IsTransient, _retryCount.Value));
            }
            else if (ExponentialBackoffConfiguration != null)
            {
                var config = ExponentialBackoffConfiguration;
                return(RetryPolicyFactory.GetExponentialPolicy(policy.IsTransient, config.RetryCount, config.MinBackoff, config.MaxBackoff, config.DeltaBackoff));
            }
            else
            {
                return(RetryPolicyFactory.GetExponentialPolicy(policy.IsTransient));
            }
        }
Exemplo n.º 8
0
        /// <nodoc />
        public ServiceClientContentStoreConfiguration(
            string cacheName,
            ServiceClientRpcConfiguration rpcConfiguration,
            string?scenario = null)
        {
            Contract.RequiresNotNullOrEmpty(cacheName);
            CacheName        = cacheName;
            RpcConfiguration = rpcConfiguration;
            Scenario         = scenario;

            _retryPolicy = new Lazy <IRetryPolicy>(
                () =>
            {
                var strategy = new TransientErrorDetectionStrategy();
                return(RetryPolicyFactory.GetLinearPolicy(
                           shouldRetry: e => strategy.IsTransient(e),
                           (int)RetryCount,
                           TimeSpan.FromSeconds(RetryIntervalSeconds)));
            });
        }