/// <summary> /// Handles request synchronously in the context of the calling thread. Returns NULL for one-way calls /// </summary> public ResponseMsg HandleRequestSynchronously(RequestMsg request) { try { return(inspectAndHandleRequest(request)); } catch (Exception error) //nothing may leak { if (request.OneWay) { //because it is one-way, the caller will never know about it this.WriteLog(LogSrc.Server, MessageType.Error, string.Format(StringConsts.GLUE_SERVER_ONE_WAY_CALL_ERROR + error.ToMessageWithType()), from: "SrvrHndlr.HandleRequestSynchronously(ReqMsg)", exception: error ); return(null); } else { //call goes via Glue because there may be some global event handlers var response = Glue.ServerHandleRequestFailure(request.RequestID, request.OneWay, error, request.BindingSpecificContext); return(response); } } finally { NFX.ApplicationModel.ExecutionContext.__SetThreadLevelSessionContext(null); } }
protected override CallSlot DoSendRequest(ClientEndPoint endpoint, RequestMsg request, CallOptions options) { request.__setServerTransport(findServerTransport(endpoint)); //notice: no serialization because we are in the same address space ResponseMsg response; try { response = Glue.ServerHandleRequest(request); } catch (Exception e) { response = Glue.ServerHandleRequestFailure(request.RequestID, request.OneWay, e, request.BindingSpecificContext); } if (request.OneWay) { return(new CallSlot(endpoint, this, request, CallStatus.Dispatched, options.TimeoutMs)); } var result = new CallSlot(endpoint, this, request, CallStatus.ResponseOK); result.DeliverResponse(response); return(result); }
private bool sendResponse(ResponseMsg response) { try { MpxServerSocket socket = getSocket(response); if (socket == null || !socket.Active) { return(false); } try { sendSocketResponse(socket, response); } catch (Exception err1) { var commError = err1 is SocketException || err1 is System.IO.IOException || (err1 is ProtocolException && ((ProtocolException)err1).CloseChannel); stat_Errors(); if (commError) { throw; //do nothing - just close the channel } if (response != null) { try { var response2 = Glue.ServerHandleRequestFailure(response.RequestID, false, err1, response.BindingSpecificContext); sendSocketResponse(socket, response2); } catch (Exception e) { Binding.WriteLog( LogSrc.Server, Log.MessageType.Warning, StringConsts.GLUE_CLIENT_THREAD_ERROR + "couldn't deliver response to client's request: " + e.Message, relatedTo: response.RequestID.ToGuid(), from: "MpxServerTransport.sendResponse", exception: e); } } } return(true); } catch (Exception error) { Binding.WriteLog(LogSrc.Server, Log.MessageType.Error, error.ToMessageWithType(), "MpxServerTransport.sendResponse()", error); if (error is MessageSizeException) { return(true); } return(false); } }
/// <summary> /// Handles request in the context of ServerHandler thread, replying back to result queue /// </summary> public void HandleRequestAsynchronously(RequestMsg request) { //todo In Future may supply Request.LongRunning to better predict thread allocation Task.Factory.StartNew( (r) => { var req = (RequestMsg)r; ResponseMsg response; try { response = HandleRequestSynchronously(req); } catch (Exception e1) { try { //call goes via Glue because there may be some global event handlers response = Glue.ServerHandleRequestFailure(req.RequestID, req.OneWay, e1, req.BindingSpecificContext); } catch (Exception e2) { this.WriteLog(LogSrc.Server, MessageType.Error, string.Format(StringConsts.GLUE_SERVER_HANDLER_ERROR + e2.ToMessageWithType()), from: "SrvrHndlr.HndlReqAsnly(ReqMsg:A)", exception: e2 ); return; } } if (!req.OneWay) { try { req.ServerTransport.SendResponse(response); } catch (Exception error) { this.WriteLog(LogSrc.Server, MessageType.Error, string.Format(StringConsts.GLUE_SERVER_HANDLER_ERROR + error.ToMessageWithType()), from: "SrvrHndlr.HndlReqAsnly(ReqMsg:B)", exception: error ); } } }, request); }
private void clientThreadSpinBody(TcpClient client, SlimSerializer serializer) //executes in its own thread { const int POLL_WAIT_MS = 5000; const int POLL_WAIT_MCRS = POLL_WAIT_MS * 1000;//microsecond using (var ms = new MemoryStream(Consts.DEFAULT_SERIALIZER_STREAM_CAPACITY)) using (client) { ms.SetLength(Consts.DEFAULT_SERIALIZER_STREAM_CAPACITY); client.LingerState.Enabled = false; client.NoDelay = true; client.ReceiveBufferSize = Binding.ServerReceiveBufferSize; client.SendBufferSize = Binding.ServerSendBufferSize; client.ReceiveTimeout = Binding.ServerReceiveTimeout; client.SendTimeout = Binding.ServerSendTimeout; //20140206 DKh byte[] check = new byte[1]; var remote = client.Client.RemoteEndPoint.ToString(); int idleSpins = 0; while (Running) { RequestMsg request = null; try { //20140206 DKh ------------- if (!client.Client.Poll(POLL_WAIT_MCRS, SelectMode.SelectRead))//microseconds { //break loop upon server listener idle timeout var st = Binding.ServerTransportIdleTimeoutMs; if (st > 0) { idleSpins++; if (idleSpins * POLL_WAIT_MS > st) { //timeout happened Instrumentation.InactiveServerTransportClosedEvent.Happened(Node); Binding.WriteLog(LogSrc.Server, Log.MessageType.DebugZ, "TCPClient timed out: " + remote, from: "TIMEOUT_CHECK"); break; } } continue; } else { if (client.Client.Receive(check, SocketFlags.Peek) <= 0) { Binding.WriteLog(LogSrc.Server, Log.MessageType.DebugZ, "TCPClient disconnected: " + remote, from: "RECEIVED<=0"); break;//disconnected } idleSpins = 0;//something arrived } //-------------------------- request = getRequest(client, ms, serializer); request.__setServerTransport(this); ResponseMsg response = Glue.ServerHandleRequest(request); //This does actual server work if (!request.OneWay && response != null) { putResponse(client, ms, response, serializer); } } catch (Exception error) { var commError = error is SocketException || error is System.IO.IOException || (error is ProtocolException && ((ProtocolException)error).CloseChannel) || (error is SlimDeserializationException) || (error is SlimSerializationException && serializer.BatchTypesAdded); Binding.WriteLog(LogSrc.Server, Log.MessageType.Warning, (commError ? StringConsts.GLUE_CLIENT_THREAD_COMMUNICATION_ERROR : StringConsts.GLUE_CLIENT_THREAD_ERROR) + error.Message, from: "SyncServerTransport.clientThreadSpinBody", exception: error); stat_Errors(); if (commError) { break; //close the channel } if (request != null) { try { var response = Glue.ServerHandleRequestFailure(request.RequestID, request.OneWay, error, request.BindingSpecificContext); if (!request.OneWay && response != null) { putResponse(client, ms, response, serializer); } } catch (Exception e) { Binding.WriteLog( LogSrc.Server, Log.MessageType.Warning, StringConsts.GLUE_CLIENT_THREAD_ERROR + "couldn't deliver response to client's request: " + e.Message, relatedTo: request.RequestID.ToGuid(), from: "SyncServerTransport.clientThreadSpinBody", exception: e); } } } } } //using }