// 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); }
/** * 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]; handler.HandleRpc(ret_path, mname, pa, ret_path); } 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() ) ) ); } } }
/** * 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: if( rs.RpcTarget is Edge ) { Edge e = (Edge)rs.RpcTarget; //This definitely won't get any more responses: if( e.IsClosed && bq != null ) { bq.Close(); } } //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); } }
/** * @return the number of bytes written into the stream */ public static int Serialize(object o, Stream s) { if( o == null ) { //Not much work to do: s.WriteByte(NULL); return 1; //1 byte for null } //Else, o is some kind of object: /* * We put the most commonly used types first so we don't have to go * through a huge list everytime we serialize */ System.Type t = o.GetType(); if ( t.Equals(typeof(string)) ) { s.WriteByte(STRING_S); string val = (string)o; int bytes = NumberSerializer.WriteString(val, s); return 1 + bytes; //the typecode + the serialized string } else if ( t.IsArray ) { Type elt = t.GetElementType(); ///@todo add more array serialization types here: if( elt.Equals(typeof(byte)) || elt.Equals(typeof(int)) ) { return SerializeArray((Array)o, t, elt, s); } else { //All arrays are ILists, but this may take more space than the above return SerializeList( (IList)o, s ); } } else if ( o is IList ) { return SerializeList( (IList)o, s); } else if ( o is IDictionary ) { IDictionary dict = o as IDictionary; //Here is a map... int total_bytes = 2; //For the '{' and '}' bytes s.WriteByte(MAP_S); //Start of map: IDictionaryEnumerator my_en = dict.GetEnumerator(); while( my_en.MoveNext() ) { //Time for recursion: total_bytes += Serialize(my_en.Key, s); total_bytes += Serialize(my_en.Value, s); } s.WriteByte(MAP_E); //End of map: return total_bytes; } else if( t.Equals( typeof(bool) ) ) { //boolean value: bool b = (bool)o; if( b ) { s.WriteByte(TRUE); } else { s.WriteByte(FALSE); } return 1; } else if ( t.Equals(typeof(byte)) ) { //Unsigned byte s.WriteByte(BYTE); s.WriteByte((byte)o); return 2; } else if ( t.Equals(typeof(sbyte)) ) { s.WriteByte(SBYTE); long v = UnboxToLong(o); s.WriteByte((byte)v); return 2; } else if ( t.Equals(typeof(short)) ) { s.WriteByte(SHORT); NumberSerializer.WriteShort((short)o,s); return 3; //1 typecode + 2 bytes for short } else if ( t.Equals(typeof(ushort)) ) { s.WriteByte(USHORT); NumberSerializer.WriteUShort((ushort)o,s); return 3; //1 typecode + 2 bytes for short } else if ( t.Equals(typeof(int)) ) { s.WriteByte(INT); NumberSerializer.WriteInt((int)o,s); return 5; //1 typecode + 4 bytes for int } else if ( t.Equals(typeof(uint)) ) { s.WriteByte(UINT); NumberSerializer.WriteUInt((uint)o,s); return 5; //1 typecode + 4 bytes for uint } else if ( t.Equals(typeof(long)) ) { s.WriteByte(LONG); NumberSerializer.WriteLong((long)o,s); return 9; //1 typecode + 8 bytes for long } else if ( t.Equals(typeof(ulong)) ) { s.WriteByte(ULONG); NumberSerializer.WriteULong((ulong)o,s); return 9; //1 typecode + 8 bytes for ulong } else if ( t.Equals(typeof(float)) ) { s.WriteByte(FLOAT); NumberSerializer.WriteFloat((float)o, s); return 5; //1 typecode + 4 bytes for float } else if ( t.Equals(typeof(double)) ) { s.WriteByte(DOUBLE); NumberSerializer.WriteDouble((double)o, s); return 9; // 1 typecode + 8 bytes for double } else if ( o is Exception ) { AdrException ax = o as AdrException; if( ax == null ) { ax = new AdrException((Exception)o); } Hashtable xht = ax.ToHashtable(); //Here is a map... int total_bytes = 2; //For the 'X' and 'x' bytes s.WriteByte(EXCEPTION_S); IDictionaryEnumerator my_en = xht.GetEnumerator(); while( my_en.MoveNext() ) { //Time for recursion: total_bytes += Serialize(my_en.Key, s); total_bytes += Serialize(my_en.Value, s); } s.WriteByte(EXCEPTION_E); return total_bytes; } else if ( o is MemBlock ) { //Just serialize this as a byte array MemBlock d = (MemBlock)o; s.WriteByte(ARRAY); int total_bytes = 1; total_bytes += SerializePosNum( (ulong)d.Length, s ); //This is a byte array: s.WriteByte(BYTE); total_bytes++; //Now write each byte: d.WriteTo(s); total_bytes += d.Length; return total_bytes; } else { //This is not a supported type of object throw new Exception("Unsupported type: " + t.ToString()); } }
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); } }
/* * This is how the above is implemented to support recursion */ private static object Deserialize(Stream s, byte terminator, out bool finished ) { int type = s.ReadByte(); object result = null; finished = false; //Set the default value if( type < 0 ) { //This is an error throw new Exception("End of stream"); } else { byte typecode = (byte)type; switch( typecode ) { case STRING_S: //UTF-8 String: int bytelength = 0; result = NumberSerializer.ReadString(s, out bytelength); break; case LIST_S: //Start of a list: IList listresult = new ArrayList(); bool lfinished = false; do { //The magic of recursion. object tmp = AdrConverter.Deserialize(s, LIST_E, out lfinished); if( !lfinished ) { //If we are finished, tmp holds a meaningless null listresult.Add(tmp); } } while( false == lfinished ); result = listresult; break; case LIST_E: //End of the list: if (terminator == LIST_E) { //We were reading a list and now we are done: finished = true; } else { throw new Exception("Unexpected terminator: ) != " + terminator); } result = null; break; case MAP_S: //Start of a map: IDictionary dresult = new Hashtable(); bool mfinished = false; do { //Magical recursion strikes again object key = Deserialize(s, MAP_E, out mfinished); if( !mfinished ) { object valu = Deserialize(s); dresult.Add(key, valu); } } while (false == mfinished); result = dresult; break; case MAP_E: //End of a map: if (terminator == MAP_E) { //We were reading a list and now we are done: finished = true; } else { throw new Exception("Unexpected terminator: } != " + terminator); } result = null; break; case TRUE: result = true; break; case FALSE: result = false; break; case NULL: //Null: result = null; break; case SBYTE: //Signed byte int valy = s.ReadByte(); if( valy < 0 ) { throw new Exception("End of stream"); } result = (sbyte)valy; break; case BYTE: //Unsigned byte int valY = s.ReadByte(); if( valY < 0 ) { throw new Exception("End of stream"); } result = (byte)valY; break; case SHORT: //signed short: result = NumberSerializer.ReadShort(s); break; case USHORT: //unsigned short: result = unchecked( (ushort)NumberSerializer.ReadShort(s) ); break; case INT: //signed int: result = NumberSerializer.ReadInt(s); break; case UINT: //unsigned int: result = unchecked( (uint)NumberSerializer.ReadInt(s) ); break; case LONG: //signed long: result = NumberSerializer.ReadLong(s); break; case ULONG: //signed long: result = unchecked((ulong)NumberSerializer.ReadLong(s)); break; case FLOAT: //floating-point number result = NumberSerializer.ReadFloat(s); break; case DOUBLE: //double-precision result = NumberSerializer.ReadDouble(s); break; case EXCEPTION_S: //Start of an exception: Hashtable xht = new Hashtable(); bool xfinished = false; do { //Magical recursion strikes again object key = Deserialize(s, EXCEPTION_E, out xfinished); if( !xfinished ) { object valu = Deserialize(s); xht.Add(key, valu); } } while (false == xfinished); result = new AdrException(xht); break; case EXCEPTION_E: //End of an exception: if (terminator == EXCEPTION_E) { //We were reading a list and now we are done: finished = true; } else { throw new Exception("Unexpected terminator: x != " + terminator); } result = null; break; case ARRAY: //Array: //Read the length: object olength = Deserialize(s); //Due to boxing here, we have to be careful about unboxing, //this will get easier with generics: long length = UnboxToLong(olength); int typec = s.ReadByte(); if ( typec < 0 ) { throw new Exception("Could not read array type"); } byte atype = (byte)typec; switch (atype) { case BYTE: //unsigned byte: byte[] aBresult = new byte[length]; int read_b = s.Read(aBresult, 0, (int)length); if( read_b != length ) { throw new Exception("Could not read byte for array"); } result = aBresult; break; case INT: //signed int: int[] airesult = new int[length]; for(int i = 0; i < airesult.Length; i++) { airesult[i] = NumberSerializer.ReadInt(s); } result = airesult; break; ///@todo add more array types default: throw new Exception("Unsupported array type code: " + atype); } break; default: throw new Exception("Unexcepted typecode: " + typecode); } return result; } }
/** Serialize directly into the given byte array * @param o the object to serialize * @param dest the array to write into * @param offset the position to start at * Note, if this fails (throws an exception), it will still * modify the destination array */ public static int Serialize(object o, byte[] dest, int offset) { #if PROFILE_ADR string key; if( o == null ) { key = "<NULL>"; } else { key = o.GetType().ToString(); } lock(ADR_COUNT) { if( ADR_COUNT.ContainsKey(key) ) { ADR_COUNT[key] = ADR_COUNT[key] + 1; } else { ADR_COUNT[key] = 1; } } #endif if( o == null ) { //Not much work to do: dest[offset] = NULL; return 1; //1 byte for null } if(o is string) { dest[offset] = STRING_S; string val = (string)o; int bytes = NumberSerializer.WriteString(val, dest, offset + 1); return 1 + bytes; //the typecode + the serialized string } //Else, o is some kind of object: /* * We put the most commonly used types first so we don't have to go * through a huge list everytime we serialize */ System.Type t = o.GetType(); byte this_type; //The hashtable allows us to be faster on the several types //of lists and dictionaries that will be handled by the same code: if( _type_map.TryGetValue(t, out this_type) ) { if( this_type == LIST_S ) { return SerializeList( (IList)o, dest, offset ); } else if( this_type == MAP_S ) { return SerializeDict( (IDictionary)o, dest, offset); } } //Else, we are dealing with a less common type: if ( t.IsArray ) { Type elt = t.GetElementType(); ///@todo add more array serialization types here: if( elt.Equals(typeof(byte)) || elt.Equals(typeof(int)) ) { return SerializeArray((Array)o, t, elt, dest, offset); } else { //All arrays are ILists, but this may take more space than the above return SerializeList( (IList)o, dest, offset ); } } else if ( o is IList ) { return SerializeList( (IList)o, dest, offset ); } else if ( o is IDictionary ) { return SerializeDict( (IDictionary)o, dest, offset); } else if( t.Equals( typeof(bool) ) ) { //boolean value: bool b = (bool)o; if( b ) { dest[offset] = TRUE; } else { dest[offset] = FALSE; } return 1; } else if ( t.Equals(typeof(byte)) ) { //Unsigned byte dest[offset] = BYTE; dest[offset + 1] = (byte)o; return 2; } else if ( t.Equals(typeof(sbyte)) ) { dest[offset] = SBYTE; //Unbox: sbyte v = (sbyte)o; //Convert: dest[offset + 1] = (byte)v; return 2; } else if ( t.Equals(typeof(short)) ) { dest[offset] = SHORT; NumberSerializer.WriteShort((short)o,dest, offset + 1); return 3; //1 typecode + 2 bytes for short } else if ( t.Equals(typeof(ushort)) ) { dest[offset] = USHORT; NumberSerializer.WriteUShort((ushort)o, dest, offset + 1); return 3; //1 typecode + 2 bytes for short } else if ( t.Equals(typeof(int)) ) { dest[offset]=INT; NumberSerializer.WriteInt((int)o,dest,offset+1); return 5; //1 typecode + 4 bytes for int } else if ( t.Equals(typeof(uint)) ) { dest[offset]=UINT; NumberSerializer.WriteUInt((uint)o,dest, offset + 1); return 5; //1 typecode + 4 bytes for uint } else if ( t.Equals(typeof(long)) ) { dest[offset]=LONG; NumberSerializer.WriteLong((long)o,dest, offset + 1); return 9; //1 typecode + 8 bytes for long } else if ( t.Equals(typeof(ulong)) ) { dest[offset]=ULONG; //Unbox ulong ulv = (ulong)o; //Convert: long lv = (long)ulv; NumberSerializer.WriteLong(lv, dest, offset + 1); return 9; //1 typecode + 8 bytes for ulong } else if ( t.Equals(typeof(float)) ) { dest[offset]=FLOAT; NumberSerializer.WriteFloat((float)o, dest, offset + 1); return 5; //1 typecode + 4 bytes for float } else if ( t.Equals(typeof(double)) ) { dest[offset]=DOUBLE; NumberSerializer.WriteDouble((double)o, dest, offset + 1); return 9; // 1 typecode + 8 bytes for double } else if ( o is Exception ) { int orig = offset; AdrException ax = o as AdrException; if( ax == null ) { ax = new AdrException((Exception)o); } Hashtable xht = ax.ToHashtable(); //Here is a map... dest[offset]=EXCEPTION_S; offset += 1; IDictionaryEnumerator my_en = xht.GetEnumerator(); while( my_en.MoveNext() ) { //Time for recursion: offset += Serialize(my_en.Key, dest, offset); offset += Serialize(my_en.Value, dest, offset); } dest[offset]=EXCEPTION_E; offset += 1; return offset - orig; } else if ( o is MemBlock ) { //Just serialize this as a byte array int orig = offset; MemBlock d = (MemBlock)o; dest[offset] = ARRAY; offset += 1; int length = d.Length; offset += SerializePosNum((ulong)length, dest, offset); dest[offset] = BYTE; offset += 1; offset += d.CopyTo(dest, offset); return offset - orig; } else { //This is not a supported type of object throw new Exception("Unsupported type: " + t.ToString()); } }
public void TestWithAdrException() { AdrException ex = new AdrException(11111, new Exception()); this._mrm.CurrentInvokeState.RetValues = new object[] { ex }; this._rpc.localproxy("Foo"); }
public override bool Equals(object o) { if( o is AdrException ) { AdrException x = (AdrException)o; return (x.Code == this.Code) && (x.Message == this.Message) && (x.StackTrace == this.StackTrace); } else if (o is Exception ) { AdrException x = new AdrException((Exception)o); return this.Equals(x); } else { return false; } }
/** * 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); } }
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 }
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 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); }