예제 #1
0
        /// <summary>
        /// Get score for invoker
        /// </summary>
        /// <param name="ib"></param>
        /// <returns></returns>
        private int GetScore(InvokerBundle ib)
        {
            // not active
            if (!ib.IsActive)
            {
                return(int.MinValue);
            }

            // not connected physically
            if (ib.Channel.State != ChannelState.Idle && ib.Channel.State != ChannelState.Ready)
            {
                return(int.MinValue);
            }

            // score offset pow
            int offset = 32768;

            // default score
            int score = 0;

            // apl online (16 points)
            if (ib.IsAplOnline)
            {
                score = score + offset * 16;
            }

            // error under limit (8 points)
            if (ib.ErrorsBelowThreshold)
            {
                score = score + offset * 8;
            }

            // return score
            return(score);
        }
예제 #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="clientConfiguration"></param>
        /// <param name="connectionInfoList"></param>
        /// <param name="channelCustomSelector"></param>
        public ManagedCallInvoker(ILogger logger, GrpcClientConfiguration clientConfiguration,
                                  List <GrpcChannelConnectionData> connectionInfoList, Func <object, string, string, string> channelCustomSelector = null)
        {
            // set properteis
            _configuration         = clientConfiguration;
            _logger                = logger;
            _channelCustomSelector = channelCustomSelector;

            // create invoke bundles
            Invokers = connectionInfoList.Select(options => {
                var ch     = new Channel(options.Url, options.Port, ChannelCredentials.Insecure);
                var inv    = new DefaultCallInvoker(ch);
                var bundle = new InvokerBundle(ch, inv, options);
                return(bundle);
            }).ToList();

            // setup round robin
            _roundRobin = new RoundRobinPolicy <InvokerBundle>(Invokers, GetScore);
        }
예제 #3
0
        /// <summary>
        /// On execution completed
        /// </summary>
        /// <typeparam name="TRequest"></typeparam>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="watch"></param>
        /// <param name="method"></param>
        /// <param name="request"></param>
        /// <param name="bundle"></param>
        /// <param name="t"></param>
        private void OnExecuteCompleteHandler <TRequest, TResponse>(Stopwatch watch, Method <TRequest, TResponse> method,
                                                                    TRequest request, InvokerBundle bundle, Task <TResponse> t)
        {
            // task status
            TaskStatus status = t.Status;

            // get execution duration
            watch.Stop();
            var duration = watch.ElapsedMilliseconds;

            // get svc name
            var svcName = method.ServiceName.Split('.').Last();

            // invoker status update
            if (status == TaskStatus.RanToCompletion)
            {
                bundle.ResetError();
            }
            else
            {
                bundle.AddError();
            }

            // log end
            if (_configuration.Options.LogRequests && _logger != null)
            {
                if (status == TaskStatus.RanToCompletion)
                {
                    _logger.LogInformation("End for action {action} on client {client}  with request {@request}, response {@response} and duration {duration}.",
                                           $"{svcName}/{method.Name}", _configuration.Name, request, t.Result, duration);
                }
                else
                {
                    _logger.LogError(t.Exception, "End for failed action {action} on client {client} with request {@request} and duration {duration}.",
                                     $"{svcName}/{method.Name}", _configuration.Name, request, duration);
                }
            }

            // request end action
            try
            {
                _configuration.DataHandlers.OnRequestEnd?.Invoke(_logger, new RequestEndData
                {
                    ServiceName = svcName,
                    MethodName  = method.Name,
                    HostName    = _configuration.Name,
                    Request     = request,
                    Response    = t.Result,
                    DurationMs  = duration,
                    Exception   = t.Exception
                });
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Failed to execute reqeust end action.");
            }
        }