/** * When an error comes in, this handles it */ public void HandleError(ReqrepManager man, int message_number, ReqrepManager.ReqrepError err, ISender ret_path, object state) { Exception x = null; RpcRequestState rs = (RpcRequestState)state; Channel bq = rs.Results; switch (err) { case ReqrepManager.ReqrepError.NoHandler: x = new AdrException(-32601, "No RPC Handler on remote host"); break; case ReqrepManager.ReqrepError.HandlerFailure: x = new AdrException(-32603, "The remote RPC System had a problem"); break; case ReqrepManager.ReqrepError.Timeout: //In this case we close the Channel: if (bq != null) { bq.Close(); } break; case ReqrepManager.ReqrepError.Send: //We had some problem sending, but ignore it for now break; } if (x != null && (bq != null)) { RpcResult res = new RpcResult(ret_path, x); bq.Enqueue(res); } }
public void TestWithAdrException() { AdrException ex = new AdrException(11111, new Exception()); this._mrm.CurrentInvokeState.RetValues = new object[] { ex }; this._rpc.localproxy("Foo"); }
public void HandleRpc(ISender caller, string method, IList arguments, object request_state) { object result = null; MemBlock key; MemBlock value; int ttl; try { switch(method) { case "Register": key = MemBlock.Reference((byte[]) arguments[0]); value = MemBlock.Reference((byte[]) arguments[1]); ttl = (int) arguments[2]; result = Register(key, value, ttl); break; case "Unregister": key = MemBlock.Reference((byte[]) arguments[0]); value = MemBlock.Reference((byte[]) arguments[1]); result = Unregister(key, value); break; case "ListEntries": result = ListEntries(); break; default: throw new Exception("Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(request_state, result); }
/** * <summary>This provides faster translation for Rpc methods as well as allows * for Asynchronous Rpc calls which are required for Puts and Creates. * </summary> * <param name="caller">The ISender who made the request.</param> * <param name="method">The method requested.</param> * <param name="args">A list of arguments to pass to the method.</param> * <param name="rs">The return state sent back to the RpcManager so that it * knows who to return the result to.</param> * <exception cref="Brunet::DistributedServices::Dht::Exception">Thrown when * there the method is not Put, PutHandler, Get, Dump, or Count</exception> */ public void HandleRpc(ISender caller, string method, IList args, object rs) { object result = null; try { if (method.Equals("Put")) { MemBlock key = (byte[])args[0]; MemBlock value = (byte[])args[1]; int ttl = (int)args[2]; bool unique = (bool)args[3]; Put(key, value, ttl, unique, rs); return; } else if (method.Equals("PutHandler")) { MemBlock key = (byte[])args[0]; MemBlock value = (byte[])args[1]; int ttl = (int)args[2]; bool unique = (bool)args[3]; result = PutHandler(key, value, ttl, unique); } else if (method.Equals("Get")) { MemBlock key = (byte[])args[0]; // Hack for backwards compatibility, supports forwards too int token_pos = args.Count - 1; if (args[token_pos] == null) { result = Get(key, null); } else { result = Get(key, (byte[])args[token_pos]); } } else if (method.Equals("Dump")) { lock (_sync) { result = _data.Dump(); } } else if (method.Equals("Count")) { result = Count; } else { throw new Exception("Dht.Exception: Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); }
/** * Fires XML-RPC call and gets the job done, then returns Brunet Rpc result. * * Calls to this method come from Brunet, go to XML-RPC and return * to Brunet Overlay. So conversion needed from Adr->XmlRpc.Net->Adr */ public void BrunetRpc2XmlRpc(object xmlrpcCallState) { XmlRpcCallState state = (XmlRpcCallState)xmlrpcCallState; object ret = null; try { ret = state.XmlRpcCall(state.MethodArgs); ret = AdrXmlRpcConverter.XmlRpc2Adr(ret); } catch (Exception e) { Debug.WriteLine(e); ret = new AdrException(-32602, e); } finally { _node.EnqueueAction(new RpcSendResultAction(_rpc, state.RequestState, ret)); } }
/** * Handles RPC calls. * Note that AddXRHandler and RemoveXRHandler calls are only accepted when * they are made by local Brunet node. */ public void HandleRpc(ISender caller, string method, IList args, object rs) { if (method.Equals("AddXRHandler") || method.Equals("RemoveXRHandler")) { ReqrepManager.ReplyState s = (ReqrepManager.ReplyState)caller; ISender sender = s.ReturnPath; if (Object.ReferenceEquals(_node, sender)) { if (args.Count == 2) { if (method.Equals("AddXRHandler")) { this.AddXRHandler(args[0] as string, args[1] as string); } else { this.RemoveXRHandler(args[0] as string, args[1] as string); } _rpc.SendResult(rs, null); return; } else { throw new ArgumentException("2 arguments expected"); } } else { throw new AdrException(-32602, "This operation is only accessible for local calls"); } } else { object result = null; try { Type type = this.GetType(); MethodInfo mi = type.GetMethod(method); object[] arg_array = new object[args.Count]; args.CopyTo(arg_array, 0); result = mi.Invoke(this, arg_array); } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); } }
// Provides a method for local apps to add certificates to Brunet without // being loaded with Brunet. public void HandleRpc(ISender caller, string method, IList args, object rs) { object result = null; try { if(method.Equals("AddCertificate")) { ReqrepManager.ReplyState rqrs = caller as ReqrepManager.ReplyState; if(rqrs == null || !(rqrs.ReturnPath is Node)) { throw new Exception("Call must be made locally for security reasons!"); } string path = (string) args[0]; result = _ch.AddCertificate(path); } else { throw new Exception("Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _node.Rpc.SendResult(rs, result); }
public void HandleRpc(ISender caller, string method, IList args, object rs) { object result = null; try { if (method.Equals("GetInformation")) { result = GetInformation(); } else { throw new Exception("Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); }
protected void MapHandler(object chan, EventArgs args) { //Get the Map result: if (LogEnabled) { ProtocolLog.Write(ProtocolLog.MapReduce, String.Format("MapReduce: {0}, in MapHandler", _node.Address)); } object map_res; Channel map_chan = (Channel)chan; if (map_chan.Count == 0) { //We must have timed out trying to get the Map result map_res = new AdrException(-32000, "no map result"); } else { map_res = map_chan.Dequeue(); } if (LogEnabled) { ProtocolLog.Write(ProtocolLog.MapReduce, String.Format("MapReduce: {0}, got map result: {1}.", _node.Address, map_res)); } //The usual transactional bit: State state = _state; State old_state; State new_state; do { old_state = state; new_state = old_state.UpdateMap(map_res); state = Interlocked.CompareExchange <State>(ref _state, new_state, old_state); }while(state != old_state); //Do the first reduction: TryNextReduce(new_state, old_state, new RpcResult(null, map_res), false); }
public void HandleRpc(ISender caller, string method, IList arguments, object request_state) { object result = null; MemBlock key; MemBlock value; int ttl; try { switch (method) { case "Register": key = MemBlock.Reference((byte[])arguments[0]); value = MemBlock.Reference((byte[])arguments[1]); ttl = (int)arguments[2]; result = Register(key, value, ttl); break; case "Unregister": key = MemBlock.Reference((byte[])arguments[0]); value = MemBlock.Reference((byte[])arguments[1]); result = Unregister(key, value); break; case "ListEntries": result = ListEntries(); break; default: throw new Exception("Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(request_state, result); }
// Provides a method for local apps to add certificates to Brunet without // being loaded with Brunet. public void HandleRpc(ISender caller, string method, IList args, object rs) { object result = null; try { if (method.Equals("AddCertificate")) { ReqrepManager.ReplyState rqrs = caller as ReqrepManager.ReplyState; if (rqrs == null || !(rqrs.ReturnPath is Node)) { throw new Exception("Call must be made locally for security reasons!"); } string path = (string)args[0]; result = _ch.AddCertificate(path); } else { throw new Exception("Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _node.Rpc.SendResult(rs, result); }
public void HandleRpc(ISender caller, string method, IList args, object rs) { if(LocalUseOnly) { try { ReqrepManager.ReplyState _rs = (ReqrepManager.ReplyState) caller; Node node = (Node) _rs.ReturnPath; if(node != _node) { throw new Exception(); } } catch { AdrException e = new AdrException(-32602, new Exception("Must send from local node!")); _node.Rpc.SendResult(rs, e); return; } } object result = null; try { switch(method) { case "Create": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[]) args[0]); MemBlock value = MemBlock.Reference((byte[]) args[1]); int ttl = (int) args[2]; Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { _node.Rpc.SendResult(rs, returns.Dequeue()); }; _dht.AsyncCreate(key, value, ttl, returns); return; } case "Put": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[]) args[0]); MemBlock value = MemBlock.Reference((byte[]) args[1]); int ttl = (int) args[2]; Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { _node.Rpc.SendResult(rs, returns.Dequeue()); }; _dht.AsyncPut(key, value, ttl, returns); return; } case "Get": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[]) args[0]); Channel returns = new Channel(); returns.CloseEvent += delegate(object o, EventArgs eargs) { Hashtable []results = new Hashtable[returns.Count]; int pos = 0; while(returns.Count > 0) { results[pos++] = (Hashtable) returns.Dequeue(); } _node.Rpc.SendResult(rs, results); }; _dht.AsyncGet(key, returns); return; } case "BeginGet": { MemBlock key = MemBlock.Reference((byte[]) args[0]); result = BeginGet(key); break; } case "ContinueGet": { MemBlock token = MemBlock.Reference((byte[]) args[0]); ContinueGet(token, rs); return; } case "EndGet": { MemBlock token = MemBlock.Reference((byte[]) args[0]); EndGet(token); result = true; break; } } } catch (Exception e) { result = new AdrException(-32602, e); } _node.Rpc.SendResult(rs, result); }
public void HandleRpc(ISender caller, string method, IList args, object rs) { if (LocalUseOnly) { try { ReqrepManager.ReplyState _rs = (ReqrepManager.ReplyState)caller; Node node = (Node)_rs.ReturnPath; if (node != _node) { throw new Exception(); } } catch { AdrException e = new AdrException(-32602, new Exception("Must send from local node!")); _node.Rpc.SendResult(rs, e); return; } } object result = null; try { switch (method) { case "Create": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[])args[0]); MemBlock value = MemBlock.Reference((byte[])args[1]); int ttl = (int)args[2]; Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { _node.Rpc.SendResult(rs, returns.Dequeue()); }; _dht.AsyncCreate(key, value, ttl, returns); return; } case "Put": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[])args[0]); MemBlock value = MemBlock.Reference((byte[])args[1]); int ttl = (int)args[2]; Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { _node.Rpc.SendResult(rs, returns.Dequeue()); }; _dht.AsyncPut(key, value, ttl, returns); return; } case "Get": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[])args[0]); Channel returns = new Channel(); returns.CloseEvent += delegate(object o, EventArgs eargs) { Hashtable [] results = new Hashtable[returns.Count]; int pos = 0; while (returns.Count > 0) { results[pos++] = (Hashtable)returns.Dequeue(); } _node.Rpc.SendResult(rs, results); }; _dht.AsyncGet(key, returns); return; } case "BeginGet": { MemBlock key = MemBlock.Reference((byte[])args[0]); result = BeginGet(key); break; } case "ContinueGet": { MemBlock token = MemBlock.Reference((byte[])args[0]); ContinueGet(token, rs); return; } case "EndGet": { MemBlock token = MemBlock.Reference((byte[])args[0]); EndGet(token); result = true; break; } } } catch (Exception e) { result = new AdrException(-32602, e); } _node.Rpc.SendResult(rs, result); }
/** * <summary>Called by a Dht client to store data here, this supports both Puts * and Creates by using the unique parameter.</summary> * <remarks>Puts will store the value no matter what, Creates will only store * the value if they are the first ones to store data on that key. This is * the first part of a Put operation. This calls PutHandler on itself and * the neighbor nearest to the key, which actually places the data into the * store. The result is returned to the client upon completion of the call * to the neighbor, if that fails the data is removed locally and an exception * is sent to the client indicating failure.</remarks> * <param name="key">The index to store the data at.</param> * <param name="value">Data to store at the key.</param> * <param name="ttl">Dht lease time in seconds</param> * <param name="unique">True if this should perform a create, false otherwise. * </param> * <param name="rs">The return state sent back to the RpcManager so that it * knows who to return the result to.</param> * <returns>True on success, thrown exception on failure</returns> * <exception cref="Exception">Data is too large, unresolved remote issues, * or the create is no successful</exception> */ public bool Put(MemBlock key, MemBlock value, int ttl, bool unique, object rs) { if (value.Length > MAX_BYTES) { throw new Exception(String.Format( "Dht only supports storing data smaller than {0} bytes.", MAX_BYTES)); } PutHandler(key, value, ttl, unique); Channel remote_put = new Channel(); remote_put.CloseAfterEnqueue(); remote_put.CloseEvent += delegate(Object o, EventArgs eargs) { object result = false; try { result = remote_put.Dequeue(); RpcResult rpcResult = (RpcResult)result; result = rpcResult.Result; if (result.GetType() != typeof(bool)) { throw new Exception("Incompatible return value."); } else if (!(bool)result) { throw new Exception("Unknown error!"); } } catch (Exception e) { lock (_sync) { _data.RemoveEntry(key, value); } result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); }; try { Address key_address = new AHAddress(key); ISender s = null; var structs = _node.ConnectionTable.GetConnections(ConnectionType.Structured); // We need to forward this to the appropriate node! if (((AHAddress)_node.Address).IsLeftOf((AHAddress)key_address)) { var con = structs.GetRightNeighborOf(_node.Address); s = con.Edge; } else { var con = structs.GetLeftNeighborOf(_node.Address); s = con.Edge; } _rpc.Invoke(s, remote_put, "dht.PutHandler", key, value, ttl, unique); } catch (Exception) { lock (_sync) { _data.RemoveEntry(key, value); } throw; } return(true); }
public void HandleRpc(ISender caller, string methname, IList arguments, object request_state) { MethodInfo mi = null; /* * Lookup this method name in our table. * This uses a cache, so it should be fast * after the first time */ lock ( _sync ) { mi = (MethodInfo)_method_cache[methname]; if (mi == null) { mi = _type.GetMethod(methname); _method_cache[methname] = mi; } } if (_use_sender) { arguments = new ArrayList(arguments); arguments.Add(caller); } object[] arg_array = new object[arguments.Count]; arguments.CopyTo(arg_array, 0); //Console.Error.WriteLine("About to call: {0}.{1} with args",handler, mname); //foreach(object arg in pa) { Console.Error.WriteLine("arg: {0}",arg); } //make the following happen asynchronously in a separate thread //build an invocation record for the call WaitCallback wb = delegate(object o) { Object result = null; try { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Invoking method: {1}", _rrman.Info, mi); #endif result = mi.Invoke(_handler, arg_array); } catch (ArgumentException argx) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Argument exception. {1}", _rrman.Info, mi); #endif result = new AdrException(-32602, argx); } catch (TargetParameterCountException argx) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Parameter count exception. {1}", _rrman.Info, mi); #endif result = new AdrException(-32602, argx); } catch (TargetInvocationException x) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Exception thrown by method: {1}, {2}", _rrman.Info, mi, x.InnerException.Message); #endif if (x.InnerException is AdrException) { result = x.InnerException; } else { result = new AdrException(-32608, x.InnerException); } } catch (Exception x) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] General exception. {1}", _rrman.Info, mi); #endif result = x; } finally { _rpc.SendResult(request_state, result); } }; //Make sure we don't block while invoking the method: #if BRUNET_SIMULATOR //Don't use extra threads in the simulator case: wb(null); #else try { /* * According to MSDN, the only way this fails is if the CLR is "Hosted" * which appears to mean that it is running inside SQL server. I can't imagine * us running into that case, but let's handle it just in case. */ if (!ThreadPool.QueueUserWorkItem(wb)) { wb(null); } } catch (Exception) { wb(null); } #endif }
/** * Handles RPC calls. * Note that AddXRHandler and RemoveXRHandler calls are only accepted when * they are made by local Brunet node. */ public void HandleRpc(ISender caller, string method, IList args, object rs) { if (method.Equals("AddXRHandler") || method.Equals("RemoveXRHandler")) { ReqrepManager.ReplyState s = (ReqrepManager.ReplyState)caller; ISender sender = s.ReturnPath; if (Object.ReferenceEquals(_node, sender)) { if (args.Count == 2) { if (method.Equals("AddXRHandler")) this.AddXRHandler(args[0] as string, args[1] as string); else this.RemoveXRHandler(args[0] as string, args[1] as string); _rpc.SendResult(rs, null); return; } else { throw new ArgumentException("2 arguments expected"); } } else { throw new AdrException(-32602, "This operation is only accessible for local calls"); } } else { object result = null; try { Type type = this.GetType(); MethodInfo mi = type.GetMethod(method); object[] arg_array = new object[args.Count]; args.CopyTo(arg_array, 0); result = mi.Invoke(this, arg_array); } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); } }
/** * Fires XML-RPC call and gets the job done, then returns Brunet Rpc result. * * Calls to this method come from Brunet, go to XML-RPC and return * to Brunet Overlay. So conversion needed from Adr->XmlRpc.Net->Adr */ public void BrunetRpc2XmlRpc(object xmlrpcCallState) { XmlRpcCallState state = (XmlRpcCallState)xmlrpcCallState; object ret = null; this.XmlRpcMethod = state.MethodName; try { object[] args = (object[])AdrXmlRpcConverter.Adr2XmlRpc(state.MethodArgs); ret = this.XmlRpcCall(args); ret = AdrXmlRpcConverter.XmlRpc2Adr(ret); } catch (Exception e) { Debug.WriteLine(e); ret = new AdrException(-32602, e); } finally { _node.EnqueueAction(new RpcSendResultAction(_rpc, state.RequestState, ret)); } }
/** <summary>Called by a Dht client to store data here, this supports both Puts and Creates by using the unique parameter.</summary> <remarks>Puts will store the value no matter what, Creates will only store the value if they are the first ones to store data on that key. This is the first part of a Put operation. This calls PutHandler on itself and the neighbor nearest to the key, which actually places the data into the store. The result is returned to the client upon completion of the call to the neighbor, if that fails the data is removed locally and an exception is sent to the client indicating failure.</remarks> <param name="key">The index to store the data at.</param> <param name="value">Data to store at the key.</param> <param name="ttl">Dht lease time in seconds</param> <param name="unique">True if this should perform a create, false otherwise. </param> <param name="rs">The return state sent back to the RpcManager so that it knows who to return the result to.</param> <returns>True on success, thrown exception on failure</returns> <exception cref="Exception">Data is too large, unresolved remote issues, or the create is no successful</exception> */ public bool Put(MemBlock key, MemBlock value, int ttl, bool unique, object rs) { if(value.Length > MAX_BYTES) { throw new Exception(String.Format( "Dht only supports storing data smaller than {0} bytes.", MAX_BYTES)); } PutHandler(key, value, ttl, unique); Channel remote_put = new Channel(); remote_put.CloseAfterEnqueue(); remote_put.CloseEvent += delegate(Object o, EventArgs eargs) { object result = false; try { result = remote_put.Dequeue(); RpcResult rpcResult = (RpcResult) result; result = rpcResult.Result; if(result.GetType() != typeof(bool)) { throw new Exception("Incompatible return value."); } else if(!(bool) result) { throw new Exception("Unknown error!"); } } catch (Exception e) { lock(_sync) { _data.RemoveEntry(key, value); } result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); }; try { Address key_address = new AHAddress(key); ISender s = null; var structs = _node.ConnectionTable.GetConnections(ConnectionType.Structured); // We need to forward this to the appropriate node! if(((AHAddress)_node.Address).IsLeftOf((AHAddress) key_address)) { var con = structs.GetRightNeighborOf(_node.Address); s = con.Edge; } else { var con = structs.GetLeftNeighborOf(_node.Address); s = con.Edge; } _rpc.Invoke(s, remote_put, "dht.PutHandler", key, value, ttl, unique); } catch (Exception) { lock(_sync) { _data.RemoveEntry(key, value); } throw; } return true; }
/** <summary>This provides faster translation for Rpc methods as well as allows for Asynchronous Rpc calls which are required for Puts and Creates. </summary> <param name="caller">The ISender who made the request.</param> <param name="method">The method requested.</param> <param name="args">A list of arguments to pass to the method.</param> <param name="rs">The return state sent back to the RpcManager so that it knows who to return the result to.</param> <exception cref="Brunet::DistributedServices::Dht::Exception">Thrown when there the method is not Put, PutHandler, Get, Dump, or Count</exception> */ public void HandleRpc(ISender caller, string method, IList args, object rs) { object result = null; try { if(method.Equals("Put")) { MemBlock key = (byte[]) args[0]; MemBlock value = (byte[]) args[1]; int ttl = (int) args[2]; bool unique = (bool) args[3]; Put(key, value, ttl, unique, rs); return; } else if(method.Equals("PutHandler")) { MemBlock key = (byte[]) args[0]; MemBlock value = (byte[]) args[1]; int ttl = (int) args[2]; bool unique = (bool) args[3]; result = PutHandler(key, value, ttl, unique); } else if(method.Equals("Get")) { MemBlock key = (byte[]) args[0]; // Hack for backwards compatibility, supports forwards too int token_pos = args.Count - 1; if(args[token_pos] == null) { result = Get(key, null); } else { result = Get(key, (byte[]) args[token_pos]); } } else if(method.Equals("Dump")) { lock(_sync) { result = _data.Dump(); } } else if(method.Equals("Count")) { result = Count; } else { throw new Exception("Dht.Exception: Invalid method"); } } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(rs, result); }
protected void MapHandler(object chan, EventArgs args) { //Get the Map result: if (LogEnabled) { ProtocolLog.Write(ProtocolLog.MapReduce, String.Format("MapReduce: {0}, in MapHandler", _node.Address)); } object map_res; Channel map_chan = (Channel)chan; if( map_chan.Count == 0 ) { //We must have timed out trying to get the Map result map_res = new AdrException(-32000, "no map result"); } else { map_res = map_chan.Dequeue(); } if (LogEnabled) { ProtocolLog.Write(ProtocolLog.MapReduce, String.Format("MapReduce: {0}, got map result: {1}.", _node.Address, map_res)); } //The usual transactional bit: State state = _state; State old_state; State new_state; do { old_state = state; new_state = old_state.UpdateMap(map_res); state = Interlocked.CompareExchange<State>(ref _state, new_state, old_state); } while( state != old_state); //Do the first reduction: TryNextReduce(new_state, old_state, new RpcResult(null, map_res), false); }
/** <summary>This provides translation for Rpc methods.<\summary> <param name="caller">The ISender who made the request.<\param> <param name="method">The method requested.</param> <param name="args">A list of arguments to pass to the method.</param> <param name="req_state">The return state sent back to the RpcManager so that it knows who to return the result to.</param> <exception>Thrown when there the method is not pre-defined</exception> <remark>This handler is registered in CacheList constructor.<\remark> */ public void HandleRpc(ISender caller, string method, IList args, object req_state) { object result = null; try { if (method == "InsertHandler") { string content = (string)args[0]; double alpha = (double)args[1]; AHAddress start = (AHAddress)AddressParser.Parse((string)args[2]); AHAddress end = (AHAddress)AddressParser.Parse((string)args[3]); CacheEntry ce = new CacheEntry(content, alpha, start, end); result = InsertHandler(ce); //_rpc.SendResult(req_state,result); } else if (method == "count") { result = _cl.Count; //_rpc.SendResult(req_state,result); } else if (method == "getestimatedsize") { result = _local_network_size; //result = _network_size; //_rpc.SendResult(req_state,result); } else if (method == "medianestimatedsize") { //EstimateNetworkMean(req_state); result = _median_network_size; //_rpc.SendResult(req_state,result); } /* else if (method == "updatenetworksize") { NetworkSize = (int)(args[0]); } */ else { throw new Exception("DeetooHandler.Exception: No Handler for method: " + method); } } catch (Exception e) { result = new AdrException(-32602, e); } _rpc.SendResult(req_state,result); }
/** * This method converts the objects compatible in AdrConvertor to * objects that compatible in XMLRPC.NET library. * byte[], MemBlock -> byte[] -> string(base64) * other array -> array ( elements converted) * IDictionary -> XmlRpcStruct (key -> string) * IList -> array * float -> double * long, ulong -> string * AdrException -> XmlRpcFaultException (w/ errorCode added) * Exception -> Exception (converted by XmlRpcFaultException by xmlrpc.net) * ISender -> string (using ToString()) * short, ushort, uint, byte, sbyte -> int * null -> string.Empty */ public static object Adr2XmlRpc(object o, out bool modified) { object retval; if (o == null) { /* * If null is returned when the method is not recursively called by itself, * it is OK because XmlRpc.Net will convert it to string.Empty. * If not, the null element's outer data structure like Array and IDictionary, * which themselves allow null elements, might not be handled correctly: * XmlRpc.Net can't serialize IDictionary and Array with null elements. * So we return s.Empty directly from here */ retval = string.Empty; modified = true; return(retval); } System.Type t = o.GetType(); // byte arrays are converted to base64 strings in XmlRpc // so we treat it as a special case of array if (t == typeof(byte[])) { retval = o; modified = false; } // convert each element else if (t.IsArray) { ArrayList list = new ArrayList((ICollection)o); bool m; modified = false; for (int i = 0; i < list.Count; i++) { list[i] = Adr2XmlRpc(list[i], out m); if (m == true) { modified = true; } } retval = list.ToArray(); } //IDictionary -> XmlRpcStruct (string key) else if (o is IDictionary) { modified = true; XmlRpcStruct xrs = new XmlRpcStruct(); IDictionary dict = o as IDictionary; IDictionaryEnumerator my_en = dict.GetEnumerator(); while (my_en.MoveNext()) { object key = Adr2XmlRpc(my_en.Key); /* * XmlRpcStruct requires keys to be strings, we just use ToString() to generate * strings. */ string str_key = key.ToString(); object val = Adr2XmlRpc(my_en.Value); xrs.Add(str_key, val); } retval = xrs; } //XmlRpcSerializer doesn't recognize lists //IList -> Array else if (o is IList) { modified = true; //list -> array ArrayList list = new ArrayList((ICollection)o); for (int i = 0; i < list.Count; i++) { list[i] = Adr2XmlRpc(list[i]); } retval = list.ToArray(); } //Memblock -> byte[] else if (o is MemBlock) { modified = true; MemBlock mb = (MemBlock)o; byte[] b = new byte[mb.Length]; mb.CopyTo(b, 0); retval = b; } //float -> double else if (t == typeof(Single)) { retval = Convert.ToDouble(o); modified = true; } else if (t == typeof(short) || t == typeof(ushort) || t == typeof(uint) || t == typeof(byte) || t == typeof(sbyte)) { retval = Convert.ToInt32(o); modified = true; } //long-> string else if (t == typeof(long) || t == typeof(ulong)) { retval = Convert.ToString(o); modified = true; } //AdrException is different from others that it has a code that can //be assigned to XmlRpcFaultException else if (o is AdrException) { AdrException e = (AdrException)o; StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("{0}", e.ToString())); retval = new XmlRpcFaultException(e.Code, sb.ToString()); modified = true; } //Still exceptions, XmlRpc.net converts it to XmlRpcFaultException else if (o is Exception) { Exception e = (Exception)o; StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("{0}", e.ToString())); retval = new Exception(sb.ToString()); modified = true; } else if (o is ISender) { ISender s = (ISender)o; retval = s.ToString(); modified = true; } else { retval = o; modified = false; } return(retval); }
public void HandleRpc(ISender caller, string methname, IList arguments, object request_state) { MethodInfo mi = null; /* * Lookup this method name in our table. * This uses a cache, so it should be fast * after the first time */ lock ( _sync ) { mi = (MethodInfo)_method_cache[methname]; if (mi == null) { mi = _type.GetMethod(methname); _method_cache[methname] = mi; } } if (_use_sender) { arguments = new ArrayList(arguments); arguments.Add(caller); } object[] arg_array = new object[arguments.Count]; arguments.CopyTo(arg_array, 0); //Console.Error.WriteLine("About to call: {0}.{1} with args",handler, mname); //foreach(object arg in pa) { Console.Error.WriteLine("arg: {0}",arg); } //make the following happen asynchronously in a separate thread //build an invocation record for the call Object result = null; try { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Invoking method: {1}", _rrman.Info, mi); #endif result = mi.Invoke(_handler, arg_array); } catch (ArgumentException argx) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Argument exception. {1}", _rrman.Info, mi); #endif result = new AdrException(-32602, argx); } catch (TargetParameterCountException argx) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Parameter count exception. {1}", _rrman.Info, mi); #endif result = new AdrException(-32602, argx); } catch (TargetInvocationException x) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Exception thrown by method: {1}, {2}", _rrman.Info, mi, x.InnerException.Message); #endif if (x.InnerException is AdrException) { result = x.InnerException; } else { result = new AdrException(-32608, x.InnerException); } } catch (Exception x) { #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] General exception. {1}", _rrman.Info, mi); #endif result = x; } finally { _rpc.SendResult(request_state, result); } }
/** * When requests come in this handles it */ public void HandleData(MemBlock payload, ISender ret_path, object state) { Exception exception = null; #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Getting method invocation request at: {1}.", _rrman.Info, DateTime.Now); #endif try { object data = AdrConverter.Deserialize(payload); IList l = data as IList; if (l == null) { //We could not cast the request into a list... so sad: throw new AdrException(-32600, "method call not a list"); } string methname = (string)l[0]; #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Getting invocation request, method: {1}", _rrman.Info, methname); #endif /* * Lookup this method name in our table. * This uses a cache, so it should be fast * after the first time */ IRpcHandler handler = null; string mname = null; lock ( _sync ) { object[] info = (object[])_method_cache[methname]; if (info == null) { int dot_idx = methname.IndexOf('.'); if (dot_idx == -1) { throw new AdrException(-32601, "No Handler for method: " + methname); } string hname = methname.Substring(0, dot_idx); //Skip the '.': mname = methname.Substring(dot_idx + 1); handler = (IRpcHandler)_method_handlers[hname]; if (handler == null) { //No handler for this. throw new AdrException(-32601, "No Handler for method: " + methname); } info = new object[2]; info[0] = handler; info[1] = mname; _method_cache[methname] = info; } else { handler = (IRpcHandler)info[0]; mname = (string)info[1]; } } ArrayList pa = (ArrayList)l[1]; #if DAVID_ASYNC_INVOKE object[] odata = new object[4]; odata[0] = handler; odata[1] = ret_path; odata[2] = mname; odata[3] = pa; _rpc_command.Enqueue(odata); #else handler.HandleRpc(ret_path, mname, pa, ret_path); #endif } catch (ArgumentException argx) { exception = new AdrException(-32602, argx); } catch (TargetParameterCountException argx) { exception = new AdrException(-32602, argx); } catch (Exception x) { exception = x; } if (exception != null) { //something failed even before invocation began #if RPC_DEBUG Console.Error.WriteLine("[RpcServer: {0}] Something failed even before invocation began: {1}", _rrman.Info, exception); #endif using (MemoryStream ms = new MemoryStream()) { AdrConverter.Serialize(exception, ms); ret_path.Send(new CopyList(PType.Protocol.Rpc, MemBlock.Reference(ms.ToArray()))); } } }