public void ProcessedRequestWithException(Request request, Exception exception) { lock (writeLock) { writer.WriteLine("Exception: {0} for scope '{1}'", request.Path, request.ServiceScope); WriteException(exception); } }
public async Task<Response> SendAsync(string host, int port, Request request, int? timeoutMilliseconds) { var uri = string.Format("http://{0}:{1}/{2}?scope={3}", host, port, request.Path, request.ServiceScope); var content = new ByteArrayContent(request.Data ?? new byte[0]); //content.Headers.Add("scope", request.ServiceScope); var httpClient = httpClients.GetOrAdd(timeoutMilliseconds ?? NoTimeout, CreateLazyHttpClient).Value; var httpResponseMessage = await httpClient.PostAsync(uri, content); var responseData = await httpResponseMessage.Content.ReadAsByteArrayAsync(); return new Response((ResponseStatus)httpResponseMessage.StatusCode, responseData); }
public Response Process(Request request) { try { logger.IncomingRequest(request); var startTime = DateTime.Now; var implementationInfo = serviceImplementationContainer.GetImplementation(request.Path.ServiceName, request.ServiceScope); if (implementationInfo.Implementation.State == ServiceImplementationState.NotInitialized) ThreadGuard.RunOnce(implementationInfo.Implementation, x => x.Initialize(clientServer, clientServer.Settings.GetServiceSettings(request.Path.ServiceName), request.ServiceScope)); if (implementationInfo.Implementation.State == ServiceImplementationState.NotInitialized) return Response.InvalidImplementation; if (implementationInfo.Implementation.State == ServiceImplementationState.NotReady) return Response.NotReady; var methodHandler = serviceMethodHandlerContainer.GetMethodHandler(implementationInfo, request.Path); var responseData = methodHandler(implementationInfo.Implementation, request.Data); var executionTime = DateTime.Now - startTime; logger.ProcessedRequestSuccessfully(request, executionTime); return new Response(ResponseStatus.Ok, responseData); } catch (ServiceNotFoundException) { logger.ProcessedRequestWithBadStatus(request, ResponseStatus.ServiceNotFound); return Response.NotFound; } catch (InvalidPathException) { logger.ProcessedRequestWithBadStatus(request, ResponseStatus.BadRequest); return Response.BadRequest; } catch (InvalidImplementationException) { logger.ProcessedRequestWithBadStatus(request, ResponseStatus.InvalidImplementation); return Response.InvalidImplementation; } catch (Exception ex) { logger.ProcessedRequestWithException(request, ex); var responseData = exceptionCodec.EncodeSingle(ex); return new Response(ResponseStatus.Exception, responseData); } }
public byte[] Process(Type serviceInterface, string pathSeparatedBySlashes, string serviceScope, byte[] data) { ServicePath path; if (!ServicePath.TryParse(pathSeparatedBySlashes, out path)) throw new InvalidOperationException(string.Format("'{0}' is not a valid service path", pathSeparatedBySlashes)); var serviceName = serviceInterface.GetServiceName(); var endPoint = topology.GetEndPoint(serviceName, serviceScope); var sender = requestSenderContainer.GetSender(endPoint.Protocol); var request = new Request(path, serviceScope, data); Response response; try { response = sender.Send(endPoint.Host, endPoint.Port, request); } catch (Exception ex) { throw new ServiceNetworkException(string.Format("Sending a '{0}' request to {1} failed", pathSeparatedBySlashes, endPoint), ex); } switch (response.Status) { case ResponseStatus.Ok: return response.Data; case ResponseStatus.NotReady: throw new NotImplementedException(); case ResponseStatus.BadRequest: throw new ServiceTopologyException(string.Format("'{0}' seems to be a bad request for {1}", pathSeparatedBySlashes, endPoint)); case ResponseStatus.ServiceNotFound: throw new ServiceTopologyException(string.Format("'{0}' service was not present at {1}", serviceName, endPoint)); case ResponseStatus.Exception: { Exception remoteException; if (exceptionCodec.TryDecodeSingle(response.Data, out remoteException)) throw remoteException; throw new ServiceNetworkException( string.Format("'{0}' request caused {1} to return an unknown exception", pathSeparatedBySlashes, endPoint)); } case ResponseStatus.InternalServerError: throw new Exception(string.Format("'{0}' request caused {1} to encounter an internal server error", pathSeparatedBySlashes, endPoint)); default: throw new ArgumentOutOfRangeException(); } }
public async Task<Response> Process(Request request) { try { logger.IncomingRequest(request); var startTime = DateTime.Now; var implementationInfo = serviceImplementationContainer.GetImplementation(request.Path.ServiceName, request.ServiceScope); var methodHandler = handlerContainer.GetHandler(implementationInfo.Description, request.Path); var responseData = await methodHandler.Handle(implementationInfo.Implementation, request.Data, 0); var executionTime = DateTime.Now - startTime; logger.ProcessedRequestSuccessfully(request, executionTime); return new Response(ResponseStatus.Ok, responseData); } catch (ServiceNotReadyException) { logger.ProcessNotReady(request); return Response.NotReady; } catch (ServiceNotFoundException) { logger.ProcessedRequestWithBadStatus(request, ResponseStatus.ServiceNotFound); return Response.NotFound; } catch (InvalidPathException) { logger.ProcessedRequestWithBadStatus(request, ResponseStatus.BadRequest); return Response.BadRequest; } catch (InvalidImplementationException) { logger.ProcessedRequestWithBadStatus(request, ResponseStatus.InvalidImplementation); return Response.InvalidImplementation; } catch (Exception ex) { logger.ProcessedRequestWithException(request, ex); var responseData = exceptionCodec.EncodeSingle(ex); return new Response(ResponseStatus.Exception, responseData); } }
public ServiceTimeoutException(Request request, int attempts, int retryMilliseconds) : base(string.Format("Request '{0}' for scope '{1}' has been attempted maximum number of times ({2}, {3}ms between each)", request.Path, request.ServiceScope, attempts, retryMilliseconds)) { }
public ServiceTimeoutException(Request request, int timeout, Exception innerException) : base(string.Format("Request '{0}' for scope '{1}' has timed out ({2})", request.Path, request.ServiceScope, timeout), innerException) { }
public void ProcessedRequestWithBadStatus(Request request, ResponseStatus responseStatus) { Console.WriteLine("Error ({0}): {1} for scope '{2}'", responseStatus, request.Path, request.ServiceScope); }
public void ProcessedRequestSuccessfully(Request request, TimeSpan executionTime) { Console.WriteLine("Success: {0} for scope '{1}' within {2} ms", request.Path, request.ServiceScope, executionTime.TotalMilliseconds); }
public void IncomingRequest(Request request) { Console.WriteLine("Incoming: {0} for scope '{1}'", request.Path, request.ServiceScope); }
public void ProcessNotReady(Request request) { lock (writeLock) writer.WriteLine("Not ready for request '{0}' for scope '{1}'", request.Path, request.ServiceScope); }
public void ProcessedRequestSuccessfully(Request request, TimeSpan executionTime) { lock (writeLock) writer.WriteLine("{0} Success: {1} for scope '{2}' within {3} ms", DateTime.Now - start, request.Path, request.ServiceScope, Math.Round(executionTime.TotalMilliseconds)); }
public void IncomingRequest(Request request) { lock (writeLock) writer.WriteLine("{0} Incoming: {1} for scope '{2}'", DateTime.Now - start, request.Path, request.ServiceScope); }
public void ProcessNotReady(Request request) { Console.WriteLine("Not ready for request '{0}' for scope '{1}'", request.Path, request.ServiceScope); }
public async Task<byte[]> ProcessAsync(Type serviceInterface, string pathSeparatedBySlashes, string serviceScope, byte[] data, TimeoutSettings timeoutSettings) { ServicePath path; if (!ServicePath.TryParse(pathSeparatedBySlashes, out path)) throw new InvalidOperationException(string.Format("'{0}' is not a valid service path", pathSeparatedBySlashes)); var serviceName = serviceInterface.GetServiceName(); var endPoint = topology.GetEndPoint(serviceName, serviceScope); var sender = requestSenderContainer.GetSender(endPoint.Protocol); var request = new Request(path, serviceScope, data); timeoutSettings = timeoutSettings ?? TimeoutSettings.NoTimeout; bool hasNetworkTimeout = timeoutSettings.MaxMilliseconds != -1 && timeoutSettings.MaxMilliseconds != 0 && timeoutSettings.MaxMilliseconds != int.MaxValue; var startTime = DateTime.Now; int remainingTriesMinusOne = timeoutSettings.NotReadyRetryCount; while (remainingTriesMinusOne >= 0) { remainingTriesMinusOne--; Response response; try { int? networkTimeout = hasNetworkTimeout ? timeoutSettings.MaxMilliseconds - (DateTime.Now - startTime).Milliseconds : (int?)null; response = await sender.SendAsync(endPoint.Host, endPoint.Port, request, networkTimeout); } catch (TimeoutException ex) { throw new ServiceTimeoutException(request, timeoutSettings.MaxMilliseconds, ex); } catch (Exception ex) { throw new ServiceNetworkException(string.Format("Sending a '{0}' request to {1} failed", pathSeparatedBySlashes, endPoint), ex); } switch (response.Status) { case ResponseStatus.Ok: return response.Data; case ResponseStatus.NotReady: if (remainingTriesMinusOne >= 0) await Task.Delay(timeoutSettings.NotReadyRetryMilliseconds); break; case ResponseStatus.BadRequest: throw new ServiceTopologyException(string.Format("'{0}' seems to be a bad request for {1}", pathSeparatedBySlashes, endPoint)); case ResponseStatus.ServiceNotFound: throw new ServiceTopologyException(string.Format("'{0}' service was not present at {1}", serviceName, endPoint)); case ResponseStatus.Exception: { Exception remoteException; if (exceptionCodec.TryDecodeSingle(response.Data, out remoteException)) throw remoteException; throw new ServiceNetworkException( string.Format("'{0}' request caused {1} to return an unknown exception", pathSeparatedBySlashes, endPoint)); } case ResponseStatus.InternalServerError: throw new Exception(string.Format("'{0}' request caused {1} to encounter an internal server error", pathSeparatedBySlashes, endPoint)); default: throw new Exception(string.Format("'{0}' request caused {1} to return an undefined status '{2}'", pathSeparatedBySlashes, endPoint, (int)response.Status)); } } throw new ServiceTimeoutException(request, timeoutSettings.NotReadyRetryCount, timeoutSettings.NotReadyRetryMilliseconds); }