/** * @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; } }
// Methods ///// /** Create a ReplyState for a new Request * Note, this is not synchronized, you must hold the lock when calling! */ protected ReplyState GenerateReplyState(PType prefix, RequestKey rk) { var rs = new ReplyState(_prefix, rk); _reply_cache[rk] = rs; rs.LocalID = _reply_id_table.GenerateID(rs); return(rs); }
/** * @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; } }
/// <summary>A new identifier pair, may be incoming or outgoing.</summary> public int Add(IIdentifierPair idpair) { int local = 0; lock (_local_to_idpair) { local = _local_to_idpair.GenerateID(idpair); } try { idpair.LocalID = local; } catch { // Another idpairtext added the local id first... lock (_local_to_idpair) { _local_to_idpair.TryTake(local, out idpair); } } return(idpair.LocalID); }