public async Task <RPCResponseMessage> InvokeMethodAsync(RPCRequestMessage messageRq, CancellationToken cancellationToken)
        {
            if (!_shouldBeConnected)
            {
                await ConnectAsync().ConfigureAwait(false);
            }
            if (_connectionCancellationToken.IsCancellationRequested)
            {
                return(null);
            }
            var handler = new RpcMessageHandler();

            while (!_messageResponsesHandlers.TryAdd(messageRq.MessageId, handler))
            {
                await Task.Delay(1).ConfigureAwait(false);
            }
            if (_currentIndex > ResetIndex)
            {
                _currentIndex = -1;
            }
            bool      sent;
            RpcClient client;

            using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_connectionCancellationToken, cancellationToken))
            {
                do
                {
                    client = _clients[Interlocked.Increment(ref _currentIndex) % _socketsPerClient];
                    sent   = await client.SendRpcMessageAsync(messageRq).ConfigureAwait(false);

                    if (!sent)
                    {
                        try
                        {
                            await client.DisconnectAsync();

                            await client.ConnectAsync();
                        }
                        catch (Exception ex)
                        {
                            Core.Log.Write(ex);
                        }
                    }
                } while (!sent);
                await handler.Event.WaitAsync(InvokeMethodTimeout, linkedTokenSource.Token).ConfigureAwait(false);
            }

            if (handler.Event.IsSet)
            {
                return(handler.Message);
            }
            _connectionCancellationToken.ThrowIfCancellationRequested();
            if (cancellationToken.IsCancellationRequested)
            {
                await client.SendRpcMessageAsync(new RPCCancelMessage { MessageId = messageRq.MessageId }).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
            }
            throw new TimeoutException("Timeout of {0} seconds has been reached waiting the response from the server with Id={1}.".ApplyFormat(InvokeMethodTimeout / 1000, messageRq.MessageId));
        }
示例#2
0
        public async Task <ServiceDescriptorCollection> GetDescriptorsAsync()
        {
            var request  = RPCRequestMessage.Retrieve(Guid.Empty, null, false);
            var response = await InvokeMethodAsync(request).ConfigureAwait(false);

            RPCRequestMessage.Store(request);
            return((ServiceDescriptorCollection)response.ReturnValue);
        }
        public async Task <ServiceDescriptorCollection> GetDescriptorsAsync()
        {
            var request = new RPCRequestMessage {
                MethodId = Guid.Empty
            };
            var response = await InvokeMethodAsync(request).ConfigureAwait(false);

            return((ServiceDescriptorCollection)response.ReturnValue);
        }
示例#4
0
        public static MethodEventArgs Retrieve(Guid clientId, RPCRequestMessage request, CancellationToken cancellationToken)
        {
            var mEvent = ReferencePool <MethodEventArgs> .Shared.New();

            mEvent.ClientId          = clientId;
            mEvent.Request           = request;
            mEvent.CancellationToken = cancellationToken;
            return(mEvent);
        }
示例#5
0
            public async ValueTask <RPCResponseMessage> ProcessRequestAsync(RPCRequestMessage request, Guid clientId, MethodDescriptor mDesc, CancellationToken cancellationToken)
            {
                var response            = RPCResponseMessage.Retrieve(request);
                var threadClientIdIndex = Environment.CurrentManagedThreadId % MaxSupportedThreadCounts;

                _threadClientId[threadClientIdIndex] = clientId;
                ConnectionCancellationToken          = cancellationToken;
                var initTime = Stopwatch.GetTimestamp();

                try
                {
                    var results = mDesc.Method(ServiceInstance, request.Parameters);
                    if (mDesc.ReturnIsTask)
                    {
                        var resultTask = (Task)results;
                        await resultTask.ConfigureAwait(false);

                        if (mDesc.ReturnTaskResult != null)
                        {
                            response.ReturnValue = mDesc.ReturnTaskResult.GetValue(resultTask);
                        }
                        else
                        {
                            response.ReturnValue = null;
                        }
                    }
                    else
                    {
                        response.ReturnValue = results;
                    }
                }
                catch (TargetInvocationException ex)
                {
                    Core.Log.Error("Error calling the Method: {0} with Parameters: [{1}], on the Service: {2}", mDesc?.Name, mDesc?.Parameters?.Select(p => p.Name + "(" + p.Type + ")").Join(","), Descriptor?.Name);
                    Core.Log.Error("Trying to call with the following parameters: {0}", request?.Parameters?.Select(s => s?.GetType().FullName ?? "(null)").Join(","));
                    Core.Log.Write(ex);
                    response.Exception = new SerializableException(ex.InnerException);
                }
                catch (Exception ex)
                {
                    Core.Log.Error("Error calling the Method: {0} with Parameters: [{1}], on the Service: {2}", mDesc?.Name, mDesc?.Parameters?.Select(p => p.Name + "(" + p.Type + ")").Join(","), Descriptor?.Name);
                    Core.Log.Error("Trying to call with the following parameters: {0}", request?.Parameters?.Select(s => s?.GetType().FullName ?? "(null)").Join(","));
                    Core.Log.Write(ex);
                    response.Exception = new SerializableException(ex);
                }
                _threadClientId[threadClientIdIndex] = Guid.Empty;
                var execTime = (Stopwatch.GetTimestamp() - initTime) * 1000d / Stopwatch.Frequency;

                mDesc.Counter.Add(execTime);
                return(response);
            }
示例#6
0
        public async Task <RPCResponseMessage> InvokeMethodAsync(RPCRequestMessage messageRq, CancellationToken cancellationToken)
        {
            if (!_shouldBeConnected)
            {
                await ConnectAsync().ConfigureAwait(false);
            }
            if (_connectionCancellationToken.IsCancellationRequested)
            {
                return(null);
            }
            var handler = _messageHandlerPool.New();

            while (!_messageResponsesHandlers.TryAdd(messageRq.MessageId, handler))
            {
                await Task.Yield();
            }
            if (_currentIndex > ResetIndex)
            {
                _currentIndex = -1;
            }
            bool      sent;
            RpcClient client;

            using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_connectionCancellationToken, cancellationToken))
            {
                do
                {
                    client = _clients[Interlocked.Increment(ref _currentIndex) % _socketsPerClient];
                    sent   = await client.SendRpcMessageAsync(messageRq).ConfigureAwait(false);
                } while (!sent);
                await handler.Event.WaitAsync(InvokeMethodTimeout, linkedTokenSource.Token).ConfigureAwait(false);
            }
            if (handler.Event.IsSet)
            {
                var msg = handler.Message;
                _messageHandlerPool.Store(handler);
                return(msg);
            }
            _messageHandlerPool.Store(handler);
            _connectionCancellationToken.ThrowIfCancellationRequested();
            if (cancellationToken.IsCancellationRequested)
            {
                await client.SendRpcMessageAsync(new RPCCancelMessage { MessageId = messageRq.MessageId }).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
            }
            throw new TimeoutException($"Timeout of {InvokeMethodTimeout / 1000} seconds has been reached waiting the response from the server with Id={messageRq.MessageId}.");
        }
示例#7
0
            public RPCResponseMessage ProcessRequest(RPCRequestMessage request, Guid clientId, MethodDescriptor mDesc, CancellationToken cancellationToken)
            {
                var response = RPCResponseMessage.Retrieve(request);

                try
                {
                    lock (_threadClientId) _threadClientId[Environment.CurrentManagedThreadId] = clientId;
                    ConnectionCancellationToken = cancellationToken;
                    var results = mDesc.Method(ServiceInstance, request.Parameters);
                    if (results is Task resultTask)
                    {
                        resultTask.WaitAsync();
                        var type = results.GetType();
                        if (type.GenericTypeArguments.Length > 0)
                        {
                            var resultProperty = TaskResultsProperties.GetOrAdd(results.GetType(), mType => mType.GetProperty("Result").GetFastPropertyInfo());
                            response.ReturnValue = resultProperty.GetValue(resultTask);
                        }
                        else
                        {
                            response.ReturnValue = null;
                        }
                    }
                    else
                    {
                        response.ReturnValue = results;
                    }
                }
                catch (TargetInvocationException ex)
                {
                    Core.Log.Error("Error calling the Method: {0} with Parameters: [{1}], on the Service: {2}", mDesc?.Name, mDesc?.Parameters?.Select(p => p.Name + "(" + p.Type + ")").Join(","), Descriptor?.Name);
                    Core.Log.Error("Trying to call with the following parameters: {0}", request?.Parameters?.Select(s => s?.GetType().FullName ?? "(null)").Join(","));
                    Core.Log.Write(ex);
                    response.Exception = new SerializableException(ex.InnerException);
                }
                catch (Exception ex)
                {
                    Core.Log.Error("Error calling the Method: {0} with Parameters: [{1}], on the Service: {2}", mDesc?.Name, mDesc?.Parameters?.Select(p => p.Name + "(" + p.Type + ")").Join(","), Descriptor?.Name);
                    Core.Log.Error("Trying to call with the following parameters: {0}", request?.Parameters?.Select(s => s?.GetType().FullName ?? "(null)").Join(","));
                    Core.Log.Write(ex);
                    response.Exception = new SerializableException(ex);
                }
                return(response);
            }
示例#8
0
 public MethodEventArgs(Guid clientId, RPCRequestMessage request, CancellationToken cancellationToken)
 {
     ClientId          = clientId;
     Request           = request;
     CancellationToken = cancellationToken;
 }