Brunet.Messaging.ReqrepManager.SendRequest C# (CSharp) Method

SendRequest() public method

public SendRequest ( ISender sender, ReqrepType reqt, ICopyable data, IReplyHandler reply, object state ) : int
sender ISender
reqt ReqrepType
data ICopyable
reply IReplyHandler
state object
return int
  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;
    }
  }

Usage Example

Example #1
0
        /**
         * This is how you invoke a method on a remote host.
         * Results are put into the Channel.
         *
         * If you want to have an Event based approach, listen to the EnqueueEvent
         * on the Channel you pass for the results.  That will be fired
         * immediately from the thread that gets the result.
         *
         * When a result comes back, we put and RpcResult into the Channel.
         * When you have enough responses, Close the queue (please).  The code
         * will stop sending requests after the queue is closed.  If you never close
         * the queue, this will be wasteful of resources.
         *
         * @param target the sender to use when making the RPC call
         * @param q the Channel into which the RpcResult objects will be placed.
         *            q may be null if you don't care about the response.
         * @param method the Rpc method to call
         *
         * @throw Exception if we cannot send the request for some reason.
         */
        virtual public void Invoke(ISender target, Channel q, string method,
                                   params object[] args)
        {
            //build state for the RPC call
            RpcRequestState rs = new RpcRequestState();

            rs.Results   = q;
            rs.RpcTarget = target;

            object[] rpc_call = new object[2];
            rpc_call[0] = method;
            if (args != null)
            {
                rpc_call[1] = args;
            }
            else
            {
                //There are no args, which we represent as a zero length list
                rpc_call[1] = new object[0];
            }

            AdrCopyable req_copy = new AdrCopyable(rpc_call);

#if RPC_DEBUG
            Console.Error.WriteLine("[RpcClient: {0}] Invoking method: {1} on target: {2}",
                                    _rrman.Info, method, target);
#endif
            ICopyable rrpayload = new CopyList(PType.Protocol.Rpc, req_copy);
            int       reqid     = _rrman.SendRequest(target, ReqrepManager.ReqrepType.Request,
                                                     rrpayload, this, rs);

            //Make sure we stop this request when the queue is closed.
            if (q != null)
            {
                try {
                    q.CloseEvent += delegate(object qu, EventArgs eargs) {
                        _rrman.StopRequest(reqid, this);
                    };
                }
                catch {
                    if (q.Closed)
                    {
                        _rrman.StopRequest(reqid, this);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }