Пример #1
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() ) ) );
      }
    }
  }
Пример #2
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:
         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);
   }
 }
Пример #3
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);
 }
Пример #4
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);
     }
   }
Пример #5
0
  /**
   * @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());
    }
  }
Пример #6
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(1);
            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]);
            result = ContinueGet(token);
            break;
          }
          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);
    }
Пример #7
0
  /** 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());
    }
  }
Пример #8
0
  /*
   * 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;
    }

  }
Пример #9
0
 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;
   }
 }
Пример #10
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;
        // We need to forward this to the appropriate node!
        if(((AHAddress)_node.Address).IsLeftOf((AHAddress) key_address)) {
          Connection con = _node.ConnectionTable.GetRightStructuredNeighborOf((AHAddress) _node.Address);
          s = con.Edge;
        }
        else {
          Connection con = _node.ConnectionTable.GetLeftStructuredNeighborOf((AHAddress) _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;
    }
Пример #11
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);
 }