コード例 #1
0
        public Task <TResult> UseAsync <TResult>(OperationContext context, MachineLocation key, Func <TService, Task <TResult> > operation)
        {
            if (_localClient?.Location.Equals(key) == true)
            {
                return(operation(_localClient.Client));
            }

            return(_connectionAccessor.UseAsync(context, key, connectionHandle =>
            {
                var client = _clientTable.GetValue(connectionHandle, static h => h.Channel.CreateGrpcService <TService>(MetadataServiceSerializer.ClientFactory));
                return operation(client);
            }));
        }
コード例 #2
0
        private async Task <TResult> ExecuteAsync <TResult>(
            OperationContext originalContext,
            Func <OperationContext, CallOptions, IGlobalCacheService, Task <TResult> > executeAsync,
            Func <TResult, string?> extraEndMessage,
            string?extraStartMessage         = null,
            [CallerMemberName] string caller = null !)
            where TResult : ResultBase
        {
            var attempt = -1;

            using var contextWithShutdown = TrackShutdown(originalContext);
            var context       = contextWithShutdown.Context;
            var callerAttempt = $"{caller}_Attempt";

            return(await context.PerformOperationWithTimeoutAsync(
                       Tracer,
                       context =>
            {
                var callOptions = new CallOptions(
                    headers: new Metadata()
                {
                    MetadataServiceSerializer.CreateContextIdHeaderEntry(context.TracingContext.TraceId)
                },
                    deadline: _clock.UtcNow + _configuration.OperationTimeout,
                    cancellationToken: context.Token);

                return _retryPolicy.ExecuteAsync(async() =>
                {
                    await Task.Yield();

                    attempt++;

                    var stopwatch = StopwatchSlim.Start();
                    var clientCreationTime = TimeSpan.Zero;

                    var result = await context.PerformOperationAsync(Tracer, () =>
                    {
                        return _serviceClientFactory.UseAsync(context, service =>
                        {
                            clientCreationTime = stopwatch.Elapsed;

                            return executeAsync(context, callOptions, service);
                        });
                    },
                                                                     extraStartMessage: extraStartMessage,
                                                                     extraEndMessage: r => $"Attempt=[{attempt}] ClientCreationTimeMs=[{clientCreationTime.TotalMilliseconds}] {extraEndMessage(r)}",
                                                                     caller: callerAttempt,
                                                                     traceErrorsOnly: true);

                    await Task.Yield();

                    // Because we capture exceptions inside the PerformOperation, we need to make sure that they
                    // get propagated for the retry policy to kick in.
                    if (result.Exception != null)
                    {
                        result.ReThrow();
                    }

                    return result;
                }, context.Token);
            },
                       caller : caller,
                       traceErrorsOnly : true,
                       extraStartMessage : extraStartMessage,
                       extraEndMessage : r => $"Attempts=[{attempt + 1}] {extraEndMessage(r)}",
                       timeout : _configuration.OperationTimeout));
        }
コード例 #3
0
        public async Task <TResult> UseAsync <TResult>(OperationContext context, Func <T, Task <TResult> > operation)
        {
            var masterMachineLocation = await GetClientAsync(context);

            return(await _clientAccessor.UseAsync(context, masterMachineLocation, operation));
        }