/** * Abandon any attempts to get requests for the given ID. * @throw Exception if handler is not the original handler for this Request */ public void StopRequest(int request_id, IReplyHandler handler) { RequestState rs = null; lock ( _sync ) { if (!_req_state_table.TryTake(request_id, out rs)) { rs = null; } } if (rs != null) { /* * Send an ack for this reply: */ byte[] ack_payload = new byte[5]; ack_payload[0] = (byte)ReqrepType.ReplyAck; NumberSerializer.WriteInt(request_id, ack_payload, 1); ICopyable data = new CopyList(_prefix, MemBlock.Reference(ack_payload)); foreach (ISender ret_path in rs.Repliers) { try { //Try to send an ack, but if we can't, oh well... ret_path.Send(data); } catch { } } } }
/** * @param sender how to send the request * @param reqt the type of request to make * @param data the data to encapsulate and send * @param reply the handler to handle the reply * @param state some state object to attach to this request * @return the identifier for this request * */ public int SendRequest(ISender sender, ReqrepType reqt, ICopyable data, IReplyHandler reply, object state) { if (reqt != ReqrepType.Request && reqt != ReqrepType.LossyRequest) { throw new Exception("Not a request"); } TimeSpan timeout = sender is Edge ? _edge_reqtimeout : _nonedge_reqtimeout; RequestState rs = new RequestState(timeout, _acked_reqtimeout); rs.Sender = sender; rs.ReplyHandler = reply; rs.RequestType = reqt; rs.UserState = state; lock ( _sync ) { rs.RequestID = _req_state_table.GenerateID(rs); rs.Request = MakeRequest(reqt, rs.RequestID, data); } //Make sure that when we drop the lock, rs is totally initialized #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepClient: {0}] Sending a request: {1} to node: {2}", _info, rs.RequestID, sender); #endif try { rs.Send(); return(rs.RequestID); } catch { //Clean up: StopRequest(rs.RequestID, reply); throw; } }
/** * @param sender how to send the request * @param reqt the type of request to make * @param data the data to encapsulate and send * @param reply the handler to handle the reply * @param state some state object to attach to this request * @return the identifier for this request * */ public int SendRequest(ISender sender, ReqrepType reqt, ICopyable data, IReplyHandler reply, object state) { if (reqt != ReqrepType.Request && reqt != ReqrepType.LossyRequest) { throw new Exception("Not a request"); } TimeSpan timeout = _to_mgr.GetTimeOutFor(sender); RequestState rs = new RequestState(timeout, _to_mgr.AckedTimeOut); rs.Sender = sender; rs.ReplyHandler = reply; rs.RequestType = reqt; rs.UserState = state; lock ( _sync ) { rs.RequestID = _req_state_table.GenerateID(rs); rs.Request = MakeRequest(reqt, rs.RequestID, data); } //Make sure that when we drop the lock, rs is totally initialized #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepClient: {0}] Sending a request: {1} to node: {2}", _info, rs.RequestID, sender); #endif try { rs.Send(); return(rs.RequestID); } catch (SendException sx) { if (sx.IsTransient) { //I guess we will just try to resend again in the future: return(rs.RequestID); } else { //This is certainly going to fail, so fail now: StopRequest(rs.RequestID, reply); throw; } } catch { //Clean up: StopRequest(rs.RequestID, reply); throw; } }
protected void HandleReply(ReqrepType rt, int idnum, MemBlock rest, ISender ret_path) { RequestState reqs; if (_req_state_table.TryGet(idnum, out reqs)) { IReplyHandler handler = null; lock ( _sync ) { if (reqs.AddReplier(ret_path)) { TimeSpan rtt = DateTime.UtcNow - reqs.ReqDate; _to_mgr.AddReplySampleFor(reqs, ret_path, rtt); handler = reqs.ReplyHandler; } } /* * Now handle this reply */ if (null != handler) { MemBlock payload; PType pt = PType.Parse(rest, out payload); Statistics statistics = new Statistics(); statistics.SendCount = reqs.SendCount; #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepManager: {0}] Receiving reply on request id: {1}, from: {2}", _info, idnum, ret_path); #endif //Don't hold the lock while calling the ReplyHandler: bool continue_listening = handler.HandleReply(this, rt, idnum, pt, payload, ret_path, statistics, reqs.UserState); //the request has been served if (!continue_listening) { StopRequest(idnum, handler); } } } else { //We are ignoring this reply, it either makes no sense, or we have //already handled it } }
/** * Abandon any attempts to get requests for the given ID. * @throw Exception if handler is not the original handler for this Request */ public void StopRequest(int request_id, IReplyHandler handler) { RequestState rs = null; lock( _sync ) { if( !_req_state_table.TryTake(request_id, out rs)) { rs = null; } } if( rs != null ) { /* * Send an ack for this reply: */ byte[] ack_payload = new byte[5]; ack_payload[0] = (byte)ReqrepType.ReplyAck; NumberSerializer.WriteInt(request_id, ack_payload, 1); ICopyable data = new CopyList(_prefix, MemBlock.Reference(ack_payload)); foreach(ISender ret_path in rs.Repliers) { try { //Try to send an ack, but if we can't, oh well... ret_path.Send(data); } catch { } } } }
/** * @param sender how to send the request * @param reqt the type of request to make * @param data the data to encapsulate and send * @param reply the handler to handle the reply * @param state some state object to attach to this request * @return the identifier for this request * */ public int SendRequest(ISender sender, ReqrepType reqt, ICopyable data, IReplyHandler reply, object state) { if ( reqt != ReqrepType.Request && reqt != ReqrepType.LossyRequest ) { throw new Exception("Not a request"); } TimeSpan timeout = _to_mgr.GetTimeOutFor(sender); RequestState rs = new RequestState(timeout, _to_mgr.AckedTimeOut); rs.Sender = sender; rs.ReplyHandler = reply; rs.RequestType = reqt; rs.UserState = state; lock( _sync ) { rs.RequestID = _req_state_table.GenerateID(rs); rs.Request = MakeRequest(reqt, rs.RequestID, data); } //Make sure that when we drop the lock, rs is totally initialized #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepClient: {0}] Sending a request: {1} to node: {2}", _info, rs.RequestID, sender); #endif try { rs.Send(); return rs.RequestID; } catch(SendException sx) { if( sx.IsTransient ) { //I guess we will just try to resend again in the future: return rs.RequestID; } else { //This is certainly going to fail, so fail now: StopRequest(rs.RequestID, reply); throw; } } catch { //Clean up: StopRequest(rs.RequestID, reply); throw; } }
/** * Abandon any attempts to get requests for the given ID. * @throw Exception if handler is not the original handler for this Request */ public void StopRequest(int request_id, IReplyHandler handler) { RequestState rs = null; lock( _sync ) { rs = (RequestState)_req_state_table[request_id]; if( rs != null ) { if( rs.ReplyHandler != handler ) { throw new Exception( String.Format("Handler mismatch: {0} != {1}", handler, rs.ReplyHandler)); } _req_state_table.Remove( request_id ); } } if( rs != null ) { /* * Send an ack for this reply: */ byte[] ack_payload = new byte[5]; ack_payload[0] = (byte)ReqrepType.ReplyAck; NumberSerializer.WriteInt(request_id, ack_payload, 1); ICopyable data = new CopyList(PType.Protocol.ReqRep, MemBlock.Reference(ack_payload)); foreach(ISender ret_path in rs.Repliers) { try { //Try to send an ack, but if we can't, oh well... ret_path.Send(data); } catch { } } } }
/** * @param sender how to send the request * @param reqt the type of request to make * @param data the data to encapsulate and send * @param reply the handler to handle the reply * @param state some state object to attach to this request * @return the identifier for this request * */ public int SendRequest(ISender sender, ReqrepType reqt, ICopyable data, IReplyHandler reply, object state) { if ( reqt != ReqrepType.Request && reqt != ReqrepType.LossyRequest ) { throw new Exception("Not a request"); } RequestState rs = new RequestState(); rs.Sender = sender; rs.ReplyHandler = reply; rs.RequestType = reqt; rs.UserState = state; lock( _sync ) { //Get the index int next_req = 0; do { next_req = _rand.Next(); } while( _req_state_table.ContainsKey( next_req ) ); /* * Now we store the request */ rs.RequestID = next_req; rs.Request = MakeRequest(reqt, next_req, data); _req_state_table[ rs.RequestID ] = rs; } #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepClient: {0}] Sending a request: {1} to node: {2}", _info, rs.RequestID, sender); #endif try { rs.Send(); return rs.RequestID; } catch { //Clean up: StopRequest(rs.RequestID, reply); throw; } }
protected void HandleReply(ReqrepType rt, int idnum, MemBlock rest, ISender ret_path) { RequestState reqs; if (_req_state_table.TryGet(idnum, out reqs)) { IReplyHandler handler = null; lock ( _sync ) { if (reqs.AddReplier(ret_path)) { TimeSpan rtt = DateTime.UtcNow - reqs.ReqDate; /* * Let's look at how long it took to get this reply: */ if (reqs.GotAck) { //Use more standard deviations for acked messages. We //just don't want to let it run forever. _acked_reqtimeout = ComputeNewTimeOut(rtt.TotalMilliseconds, _acked_rtt_stats, _MINIMUM_TIMEOUT, 3 * _STD_DEVS); } else if (ret_path is Edge) { _edge_reqtimeout = ComputeNewTimeOut(rtt.TotalMilliseconds, _edge_rtt_stats, _MINIMUM_TIMEOUT, _STD_DEVS); } else { _nonedge_reqtimeout = ComputeNewTimeOut(rtt.TotalMilliseconds, _nonedge_rtt_stats, _MINIMUM_TIMEOUT, _STD_DEVS); } handler = reqs.ReplyHandler; } } /* * Now handle this reply */ if (null != handler) { MemBlock payload; PType pt = PType.Parse(rest, out payload); Statistics statistics = new Statistics(); statistics.SendCount = reqs.SendCount; #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepManager: {0}] Receiving reply on request id: {1}, from: {2}", _info, idnum, ret_path); #endif //Don't hold the lock while calling the ReplyHandler: bool continue_listening = handler.HandleReply(this, rt, idnum, pt, payload, ret_path, statistics, reqs.UserState); //the request has been served if (!continue_listening) { StopRequest(idnum, handler); } } } else { //We are ignoring this reply, it either makes no sense, or we have //already handled it } }
/** * @param sender how to send the request * @param reqt the type of request to make * @param data the data to encapsulate and send * @param reply the handler to handle the reply * @param state some state object to attach to this request * @return the identifier for this request * */ public int SendRequest(ISender sender, ReqrepType reqt, ICopyable data, IReplyHandler reply, object state) { if ( reqt != ReqrepType.Request && reqt != ReqrepType.LossyRequest ) { throw new Exception("Not a request"); } TimeSpan timeout = sender is Edge ? _edge_reqtimeout : _nonedge_reqtimeout; RequestState rs = new RequestState(timeout, _acked_reqtimeout); rs.Sender = sender; rs.ReplyHandler = reply; rs.RequestType = reqt; rs.UserState = state; lock( _sync ) { rs.RequestID = _req_state_table.GenerateID(rs); rs.Request = MakeRequest(reqt, rs.RequestID, data); } //Make sure that when we drop the lock, rs is totally initialized #if REQREP_DEBUG Console.Error.WriteLine("[ReqrepClient: {0}] Sending a request: {1} to node: {2}", _info, rs.RequestID, sender); #endif try { rs.Send(); return rs.RequestID; } catch { //Clean up: StopRequest(rs.RequestID, reply); throw; } }