Beispiel #1
0
        /**
         * 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);
            }
        }
Beispiel #2
0
        public void TestWithAdrException()
        {
            AdrException ex = new AdrException(11111, new Exception());

            this._mrm.CurrentInvokeState.RetValues = new object[] { ex };
            this._rpc.localproxy("Foo");
        }
Beispiel #3
0
 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);
 }
Beispiel #4
0
        /**
         * <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);
        }
Beispiel #5
0
        /**
         * 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));
            }
        }
Beispiel #6
0
 /**
  * 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);
 }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #12
0
    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);
    }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        /**
         * <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);
        }
Beispiel #15
0
            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
            }
Beispiel #16
0
 /**
  * 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);
   }
 }
Beispiel #17
0
 /**
  * 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));
   }
 }
Beispiel #18
0
 public void TestWithAdrException() {
   AdrException ex = new AdrException(11111, new Exception());
   this._mrm.CurrentInvokeState.RetValues = new object[] { ex };
   this._rpc.localproxy("Foo");
 }
Beispiel #19
0
    /**
    <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;
    }
Beispiel #20
0
 /**
 <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);
 }
Beispiel #21
0
 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);
    }
Beispiel #23
0
        /**
         * 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);
        }
Beispiel #24
0
            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);
                }
            }
Beispiel #25
0
        /**
         * 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())));
                }
            }
        }