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)); }
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); }
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); }
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); }
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}."); }
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); }
public MethodEventArgs(Guid clientId, RPCRequestMessage request, CancellationToken cancellationToken) { ClientId = clientId; Request = request; CancellationToken = cancellationToken; }