Brunet.Services.Dht.Dht.GetEnqueueHandler C# (CSharp) Méthode

GetEnqueueHandler() public méthode

This is called as a result of a successful retrieval of data from a remote end point and performs follow up gets for remaining values
This adds the results to the entry in the _adgs_table. Once a value has been received by a majority of nodes, it is enqueued into the requestors returns channel. If not all results were retrieved follow up gets are performed, this is determined by looking at the state of the token, a non-null token implies there are remaining results.
public GetEnqueueHandler ( Object o, EventArgs args ) : void
o Object The channel used to store the results.
args System.EventArgs Unused.
Résultat void
    public void GetEnqueueHandler(Object o, EventArgs args) {
      Channel queue = (Channel) o;
      // Looking up state
      AsDhtGetState adgs = (AsDhtGetState) _adgs_table[queue];

      if(adgs == null) {
        return;
      }

      int idx = (int) adgs.queueMapping[queue];
      // Test to see if we got any results and place them into results if necessary
      ISender sendto = null;
      MemBlock token = null;
      try {
        RpcResult rpc_reply = (RpcResult) queue.Dequeue();
        ArrayList result = (ArrayList) rpc_reply.Result;
        //Result may be corrupted
        if(result == null) {
          throw new Exception("Invalid result");
        }
        ArrayList values = (ArrayList) result[0];
        int remaining = (int) result[1];
        if(remaining > 0) {
          token = MemBlock.Reference((byte[]) result[2]);
          sendto = rpc_reply.ResultSender;
        }

        // Going through the return values and adding them to our
        // results, if a majority of our servers say a data exists
        // we say it is a valid data and return it to the caller
        foreach (Hashtable ht in values) {
          MemBlock mbVal = MemBlock.Reference((byte[]) ht["value"]);
          int count = 1;
          Hashtable res = null;
          lock(adgs.SyncRoot) {
            res = (Hashtable) adgs.results[mbVal];
            if(res == null) {
              res = new Hashtable();
              adgs.results[mbVal] = res;
              adgs.ttls[mbVal] = ht["ttl"];
            }
            else {
              adgs.ttls[mbVal] = (int) adgs.ttls[mbVal] + (int) ht["ttl"];
            }

            res[idx] = true;
            count = ((ICollection) adgs.results[mbVal]).Count;
          }
          if(count == MAJORITY) {
            ht["ttl"] = (int) adgs.ttls[mbVal] / MAJORITY;
            adgs.returns.Enqueue(ht);
          }
        }
      }
      catch (Exception) {
        sendto = null;
        token = null;
      }

    // We were notified that more results were available!  Let's go get them!
      if(token != null && sendto != null) {
        Channel new_queue = new Channel(1);
        lock(adgs.SyncRoot) {
          adgs.queueMapping[new_queue] = idx;
        }
        lock(_adgs_table.SyncRoot) {
          _adgs_table[new_queue] = adgs;
        }
        new_queue.EnqueueEvent += this.GetEnqueueHandler;
        new_queue.CloseEvent += this.GetCloseHandler;
        try {
          _rpc.Invoke(sendto, new_queue, "dht.Get", 
                    adgs.brunet_address_for_key[idx], token);
        }
        catch(Exception) {
          lock(adgs.SyncRoot) {
            adgs.queueMapping.Remove(new_queue);
          }
          lock(_adgs_table.SyncRoot) {
            _adgs_table.Remove(new_queue);
          }
          new_queue.EnqueueEvent -= this.GetEnqueueHandler;
          new_queue.CloseEvent -= this.GetCloseHandler;
        }
      }
    }