CloseAfterEnqueue() public method

public CloseAfterEnqueue ( ) : bool
return bool
Example #1
0
  /**
   * This is a recursive function over the network
   * It helps to build an IList of IDictionary types that give the address
   * of each node in the path, and the connection to the next closest node if
   * there is one, otherwise no next.
   */
  protected void DoTraceRouteTo(AHAddress a, object req_state) {
    /*
     * First find the Connection pointing to the node closest to dest, if
     * there is one closer than us
     */

    ConnectionTable tab = _node.ConnectionTable;
    ConnectionList structs = tab.GetConnections(ConnectionType.Structured);
    Connection next_closest = structs.GetNearestTo((AHAddress) _node.Address, a);
    //Okay, we have the next closest:
    ListDictionary my_entry = new ListDictionary();
    my_entry["node"] = _node.Address.ToString();
    if( next_closest != null ) {
      my_entry["next_con"] = next_closest.ToString();
      Channel result = new Channel();
      //We only want one result, so close the queue after we get the first
      result.CloseAfterEnqueue();
      result.CloseEvent += delegate(object o, EventArgs args) {
        Channel q = (Channel)o;
        if( q.Count > 0 ) {
          try {
            RpcResult rres = (RpcResult)q.Dequeue();
            IList l = (IList) rres.Result;
            ArrayList results = new ArrayList( l.Count + 1);
            results.Add(my_entry);
            results.AddRange(l);
            _rpc.SendResult(req_state, results);
          }
          catch(Exception x) {
            string m = String.Format("<node>{0}</node> trying <connection>{1}</connection> got <exception>{2}</exception>", _node.Address, next_closest, x);
            Exception nx = new Exception(m);
            _rpc.SendResult(req_state, nx);
          }
        }
        else {
          //We got no results.
          IList l = new ArrayList(1);
          l.Add( my_entry );
          _rpc.SendResult(req_state, l);
        }
      };
      _rpc.Invoke(next_closest.State.Edge, result, "trace.GetRouteTo", a.ToString());
    }
    else {
      //We are the end of the line, send the result:
      ArrayList l = new ArrayList();
      l.Add(my_entry);
      _rpc.SendResult(req_state, l);  
    }
  }
Example #2
0
  /**
   * This is a recursive function over the network
   * It helps do a link-reliable procedure call on the
   * on the overlay network.
   */
  protected void RecursiveCall(IList margs, object req_state) {
    //first argument is the target node.
    AHAddress a = (AHAddress) AddressParser.Parse( (string) margs[0]);
    /*
     * First find the Connection pointing to the node closest to dest, if
     * there is one closer than us
     */

    ConnectionTable tab = _node.ConnectionTable;
    ConnectionList structs = tab.GetConnections(ConnectionType.Structured);
    Connection next_closest = structs.GetNearestTo((AHAddress) _node.Address, a);
    //Okay, we have the next closest:
    if( next_closest != null ) {
      Channel result = new Channel();
      //We only want one result, so close the queue after we get the first
      result.CloseAfterEnqueue();
      result.CloseEvent += delegate(object o, EventArgs args) {
        Channel q = (Channel)o;
        if( q.Count > 0 ) {
          try {
            RpcResult rres = (RpcResult)q.Dequeue();
            _rpc.SendResult(req_state, rres.Result);
          }
          catch(Exception x) {
            string m = String.Format("<node>{0}</node> trying <connection>{1}</connection> got <exception>{2}</exception>", _node.Address, next_closest, x);
            Exception nx = new Exception(m);
            _rpc.SendResult(req_state, nx);
          }
        }
        else {
          //We got no results.
          _rpc.SendResult(req_state, null);
        }
      };
      object [] new_args = new object[margs.Count];
      margs.CopyTo(new_args, 0);
      _rpc.Invoke(next_closest.State.Edge, result, "trace.RecursiveCall", new_args);
    }
    else {
      //We are the end of the line, send the result:
      //Console.Error.WriteLine("Doing a local invocation");
      Channel result = new Channel();
      result.CloseAfterEnqueue();
      result.CloseEvent += delegate(object o, EventArgs args) {
        Channel q = (Channel)o;
        if( q.Count > 0 ) {
          try {
            //Console.Error.WriteLine("Got result.");
            RpcResult rres = (RpcResult)q.Dequeue();
            _rpc.SendResult(req_state, rres.Result);
          }
          catch(Exception x) {
            string m = String.Format("<node>{0}</node> local invocation got <exception>{1}</exception>", _node.Address, x);
            Exception nx = new Exception(m);
            _rpc.SendResult(req_state, nx);
          }
        }
        else {
          //We got no results.
          _rpc.SendResult(req_state, null);
        }        
      };

      string method_name = (string) margs[1];
      object [] new_args = new object[margs.Count - 2];
      margs.RemoveAt(0);//extract destination address
      margs.RemoveAt(0); //extract method name
      margs.CopyTo(new_args, 0);
      //Console.Error.WriteLine("Calling method: {0}, args_count: {1}", method_name, new_args.Length);
      //for (int i = 0; i < new_args.Length; i++) {
      //Console.Error.WriteLine(new_args[i]);
      //}
      _rpc.Invoke(_node, result, method_name, new_args);
    }
    
  }
Example #3
0
    /**
     * When we get a response to the sys:link method, this handled
     * is called
     */
    protected void LinkCloseHandler(object q, EventArgs args) {
      try {
        Channel resq = (Channel)q;
        //If the Channel is empty this will throw an exception:
        RpcResult res = (RpcResult)resq.Dequeue();
        /* Here's the LinkMessage response */
        LinkMessage lm = new LinkMessage( (IDictionary)res.Result );
        /**
         * This will set our LinkMessageReply variable.  It can
         * only be set once, so all future sets will fail.  It
         * will also make sure we have the lock on the target.
         * If we don't, that will throw an exception
         */
        SetAndCheckLinkReply(lm);
        //If we got here, we have our response and the Lock on _target_address
        StatusMessage sm = _node.GetStatus(_contype, lm.Local.Address);
        /* Make the call */
        Channel results = new Channel();
        results.CloseAfterEnqueue();
        results.CloseEvent += this.StatusCloseHandler;
        RpcManager rpc = _node.Rpc;
	if (ProtocolLog.LinkDebug.Enabled) {
	      ProtocolLog.Write(ProtocolLog.LinkDebug, 
                String.Format(
                  "LPS target: {0} Invoking GetStatus() over edge: {1}",
                  _linker.Target, _e));
	}
        /*
         * This could throw an exception if the Edge is closed
         */
        rpc.Invoke(_e, results, "sys:link.GetStatus", sm.ToDictionary() );
      }
      catch(AdrException x) {
        /*
         * This happens when the RPC call has some kind of issue,
         * first we check for common error conditions:
         */
        _x.Value = x;
        Finish( GetResultForErrorCode(x.Code) );
      }
      catch(ConnectionExistsException x) {
        /* We already have a connection */
        _x.Value = x;
        Finish( Result.ProtocolError );
      }
      catch(CTLockException x) {
        //This is thrown when ConnectionTable cannot lock.  Lets try again:
        _x.Value = x;
        Finish( Result.RetryThisTA );
      }
      catch(LinkException x) {
        _x.Value = x;
        if( x.IsCritical ) { Finish( Result.MoveToNextTA ); }
        else { Finish( Result.RetryThisTA ); }
      }
      catch(InvalidOperationException) {
        //The queue never got anything
        Finish(Result.MoveToNextTA);
      }
      catch(EdgeException) {
        //The Edge is goofy, let's move on:
        Finish(Result.MoveToNextTA);
      }
      catch(Exception x) {
        //The protocol was not followed correctly by the other node, fail
        _x.Value = x;
        Finish( Result.RetryThisTA );
      } 
    }
Example #4
0
    public override void Start() {
      //Make sure the Node is listening to this node
      try {
        //This will throw an exception if _e is already closed:
        _e.CloseEvent += this.CloseHandler; 
        //_e must not be closed, let's start listening to it:
        _e.Subscribe(_node, _e);
        /* Make the call */
        Channel results = new Channel();
        results.CloseAfterEnqueue();
        results.CloseEvent += this.LinkCloseHandler;
        RpcManager rpc = _node.Rpc;
	if(ProtocolLog.LinkDebug.Enabled) {
	  ProtocolLog.Write(ProtocolLog.LinkDebug, 
			    String.Format("LPS target: {0} Invoking Start() over edge: {1}", _linker.Target, _e));
	}
        rpc.Invoke(_e, results, "sys:link.Start", MakeLM().ToDictionary() );
      }
      catch (Exception e) {
        //The Edge must have closed, move on to the next TA
	if(ProtocolLog.LinkDebug.Enabled) {
	  ProtocolLog.Write(ProtocolLog.LinkDebug, 
			    String.Format("LPS target: {0} Start() over edge: {1}, hit exception: {2}", 
					  _linker.Target, _e, e));
	}
        Finish(Result.MoveToNextTA);
      }
    }
Example #5
0
  public void ChannelTests() {
    Channel c0 = new Channel();
    bool e_event_fired = false;
    c0.EnqueueEvent += delegate(object o, EventArgs arg) {
      e_event_fired = true;
    };
    c0.Enqueue(0);
    bool c_event_fired = false;
    c0.CloseEvent += delegate(object o, EventArgs arg) {
      c_event_fired = true;
    };
    c0.Close();
    Assert.IsTrue(c_event_fired, "CloseEvent");

    c0 = new Channel();
    c0.CloseAfterEnqueue();
    c_event_fired = false;
    c0.CloseEvent += delegate(object o, EventArgs arg) {
      c_event_fired = true;
    };
    c0.Enqueue(1); //This should close the channel:
    Assert.IsTrue(c_event_fired, "CloseEvent on Enqueue");
    Assert.IsTrue(c0.Closed, "Closed");
    
    c0 = new Channel(1);
    c_event_fired = false;
    c0.CloseEvent += delegate(object o, EventArgs arg) {
      c_event_fired = true;
    };
    c0.Enqueue(1); //This should close the channel:
    Assert.IsTrue(c_event_fired, "CloseEvent on Enqueue");
    Assert.IsTrue(c0.Closed, "Closed");
    //Try with different starting values:
    Random r = new Random();
    int en_count;
    for(int i = 0; i < 100; i++) {
      int max_enqueues = r.Next(1, 1000);
      c0 = new Channel(max_enqueues);
      c_event_fired = false;
      en_count = 0;
      c0.CloseEvent += delegate(object o, EventArgs arg) {
        c_event_fired = true;
      };
      c0.EnqueueEvent += delegate(object o, EventArgs arg) {
        en_count++;
      };
      for(int j = 0; j < max_enqueues; j++) {
        c0.Enqueue(j);
      }
      Assert.IsTrue(c_event_fired, "CloseEvent on Enqueue");
      Assert.AreEqual(en_count, max_enqueues, "EnqueueEvent count");
      Assert.IsTrue(c0.Closed, "Closed");
      try {
        c0.Enqueue(null);
        Assert.IsTrue(false, "Enqueue after close didn't fail");
      }
      catch {
        Assert.IsTrue(true, "Enqueue after close Got exception");
      }
    }

  }
Example #6
0
        public void ChannelTests()
        {
            Channel c0            = new Channel();
            bool    e_event_fired = false;

            c0.EnqueueEvent += delegate(object o, EventArgs arg) {
                e_event_fired = true;
            };
            c0.Enqueue(0);
            bool c_event_fired = false;

            c0.CloseEvent += delegate(object o, EventArgs arg) {
                c_event_fired = true;
            };
            c0.Close();
            Assert.IsTrue(c_event_fired, "CloseEvent");

            c0 = new Channel();
            c0.CloseAfterEnqueue();
            c_event_fired  = false;
            c0.CloseEvent += delegate(object o, EventArgs arg) {
                c_event_fired = true;
            };
            c0.Enqueue(1); //This should close the channel:
            Assert.IsTrue(c_event_fired, "CloseEvent on Enqueue");
            Assert.IsTrue(c0.Closed, "Closed");

            c0             = new Channel(1);
            c_event_fired  = false;
            c0.CloseEvent += delegate(object o, EventArgs arg) {
                c_event_fired = true;
            };
            c0.Enqueue(1); //This should close the channel:
            Assert.IsTrue(c_event_fired, "CloseEvent on Enqueue");
            Assert.IsTrue(c0.Closed, "Closed");
            //Try with different starting values:
            Random r = new Random();
            int    en_count;

            for (int i = 0; i < 100; i++)
            {
                int max_enqueues = r.Next(1, 1000);
                c0             = new Channel(max_enqueues);
                c_event_fired  = false;
                en_count       = 0;
                c0.CloseEvent += delegate(object o, EventArgs arg) {
                    c_event_fired = true;
                };
                c0.EnqueueEvent += delegate(object o, EventArgs arg) {
                    en_count++;
                };
                for (int j = 0; j < max_enqueues; j++)
                {
                    c0.Enqueue(j);
                }
                Assert.IsTrue(c_event_fired, "CloseEvent on Enqueue");
                Assert.AreEqual(en_count, max_enqueues, "EnqueueEvent count");
                Assert.IsTrue(c0.Closed, "Closed");
                try {
                    c0.Enqueue(null);
                    Assert.IsTrue(false, "Enqueue after close didn't fail");
                }
                catch {
                    Assert.IsTrue(true, "Enqueue after close Got exception");
                }
            }
        }