Example #1
0
  @Test
  public void testResponse() throws Exception {

    Context ctx = ZMQ.context(1);
    Socket router = ctx.socket(ZMQ.ROUTER);
    router.bind("tcp://127.0.0.1:6001");
    router.setEncoder(Persistence.PersistEncoder.class);

    Socket dealer = ctx.socket(ZMQ.DEALER);
    dealer.setIdentity("A");
    dealer.connect("tcp://127.0.0.1:6001");

    Thread.sleep(1000);
    router.sendMore("A");
    router.sendMore(new byte[] {Persistence.MESSAGE_RESPONSE});
    router.sendMore(new byte[] {STATUS_OK});
    router.send(ByteBuffer.wrap(new byte[8]).putLong(100).array());

    assertEquals(dealer.recv()[0], STATUS_OK);
    assertEquals(dealer.recv().length, 8);

    dealer.close();
    router.close();
    ctx.term();
  }
Example #2
0
  @Test
  public void testError() throws Exception {

    Context ctx = ZMQ.context(1);
    Socket router = ctx.socket(ZMQ.ROUTER);
    router.bind("tcp://127.0.0.1:6001");
    router.setEncoder(Persistence.PersistEncoder.class);

    Socket dealer = ctx.socket(ZMQ.DEALER);
    dealer.setIdentity("A");
    dealer.connect("tcp://127.0.0.1:6001");

    Thread.sleep(1000);
    router.sendMore("A");
    router.sendMore(new byte[] {Persistence.MESSAGE_ERROR});
    router.send(new byte[] {Persistence.STATUS_INTERNAL_ERROR});

    assertEquals(dealer.recv()[0], Persistence.STATUS_INTERNAL_ERROR);

    dealer.close();
    router.close();
    ctx.term();
  }
Example #3
0
  @Test
  public void testFile() throws Exception {

    String datadir = ".tmp";
    String longdata = "";
    for (int i = 0; i < 30; i++) longdata += "1234567890";
    String path = datadir + "/new_topic/00000000000000000000.dat";
    RandomAccessFile raf = new RandomAccessFile(path, "rw");
    FileChannel ch = raf.getChannel();
    MappedByteBuffer buf = ch.map(MapMode.READ_WRITE, 0, 1024);
    buf.put((byte) 0);
    buf.put((byte) 5);
    buf.put("12345".getBytes());
    buf.put((byte) 1); // more
    buf.put((byte) 11);
    buf.put("67890abcdef".getBytes());
    buf.put((byte) 2); // long
    buf.putLong(300);
    buf.put(longdata.getBytes());

    raf.close();
    ch.close();

    Context ctx = ZMQ.context(1);
    Socket router = ctx.socket(ZMQ.ROUTER);
    router.bind("tcp://127.0.0.1:6001");
    router.setEncoder(Persistence.PersistEncoder.class);

    Socket dealer = ctx.socket(ZMQ.DEALER);
    dealer.setIdentity("A");
    dealer.connect("tcp://127.0.0.1:6001");

    Thread.sleep(1000);
    router.sendMore("A");
    router.sendMore(new byte[] {Persistence.MESSAGE_FILE});
    router.sendMore(new byte[] {STATUS_OK});
    router.sendMore(path);
    router.sendMore(ByteBuffer.wrap(new byte[8]).putLong(0).array());
    router.send(ByteBuffer.wrap(new byte[8]).putLong(329).array());

    assertEquals(dealer.recv()[0], STATUS_OK);
    ByteBuffer content = ByteBuffer.wrap(dealer.recv());

    assertEquals(content.limit(), 329);
    assertEquals(0, content.get());
    int length = content.get();
    assertEquals(5, length);
    byte[] data = new byte[length];
    content.get(data);
    assertEquals("12345", new String(data));

    assertEquals(1, content.get());
    length = content.get();
    assertEquals(11, length);
    data = new byte[length];
    content.get(data);
    assertEquals("67890abcdef", new String(data));

    assertEquals(2, content.get());
    length = (int) content.getLong();
    assertEquals(300, length);
    data = new byte[length];
    content.get(data);
    assertEquals(longdata, new String(data));

    assertEquals(false, content.hasRemaining());

    dealer.close();
    router.close();
    ctx.term();
  }
Example #4
0
  //  The main task begins by setting-up all its sockets. The local frontend
  //  talks to clients, and our local backend talks to workers. The cloud
  //  frontend talks to peer brokers as if they were clients, and the cloud
  //  backend talks to peer brokers as if they were workers. The state
  //  backend publishes regular state messages, and the state frontend
  //  subscribes to all state backends to collect these messages. Finally,
  //  we use a PULL monitor socket to collect printable messages from tasks:
  public static void main(String[] argv) {
    //  First argument is this broker's name
    //  Other arguments are our peers' names
    //
    if (argv.length < 1) {
      System.out.println("syntax: peering3 me {you}\n");
      System.exit(-1);
    }
    self = argv[0];
    System.out.println(String.format("I: preparing broker at %s\n", self));
    Random rand = new Random(System.nanoTime());

    ZContext ctx = new ZContext();

    //  Prepare local frontend and backend
    Socket localfe = ctx.createSocket(ZMQ.ROUTER);
    localfe.bind(String.format("ipc://%s-localfe.ipc", self));
    Socket localbe = ctx.createSocket(ZMQ.ROUTER);
    localbe.bind(String.format("ipc://%s-localbe.ipc", self));

    //  Bind cloud frontend to endpoint
    Socket cloudfe = ctx.createSocket(ZMQ.ROUTER);
    cloudfe.setIdentity(self);
    cloudfe.bind(String.format("ipc://%s-cloud.ipc", self));

    //  Connect cloud backend to all peers
    Socket cloudbe = ctx.createSocket(ZMQ.ROUTER);
    cloudbe.setIdentity(self);
    int argn;
    for (argn = 1; argn < argv.length; argn++) {
      String peer = argv[argn];
      System.out.println(String.format("I: connecting to cloud forintend at '%s'\n", peer));
      cloudbe.connect(String.format("ipc://%s-cloud.ipc", peer));
    }

    //  Bind state backend to endpoint
    Socket statebe = ctx.createSocket(ZMQ.PUB);
    statebe.bind(String.format("ipc://%s-state.ipc", self));

    //  Connect statefe to all peers
    Socket statefe = ctx.createSocket(ZMQ.SUB);
    statefe.subscribe("");
    for (argn = 1; argn < argv.length; argn++) {
      String peer = argv[argn];
      System.out.println(String.format("I: connecting to state backend at '%s'\n", peer));
      statefe.connect(String.format("ipc://%s-state.ipc", peer));
    }

    //  Prepare monitor socket
    Socket monitor = ctx.createSocket(ZMQ.PULL);
    monitor.bind(String.format("ipc://%s-monitor.ipc", self));

    //  Start local workers
    int worker_nbr;
    for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++) new worker_task().start();

    //  Start local clients
    int client_nbr;
    for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++) new client_task().start();

    //  Queue of available workers
    int local_capacity = 0;
    int cloud_capacity = 0;
    ArrayList<ZFrame> workers = new ArrayList<ZFrame>();

    //  The main loop has two parts. First we poll workers and our two service
    //  sockets (statefe and monitor), in any case. If we have no ready workers,
    //  there's no point in looking at incoming requests. These can remain on
    //  their internal 0MQ queues:

    while (true) {
      //  First, route any waiting replies from workers
      PollItem primary[] = {
        new PollItem(localbe, ZMQ.POLLIN),
        new PollItem(cloudbe, ZMQ.POLLIN),
        new PollItem(statefe, ZMQ.POLLIN),
        new PollItem(monitor, ZMQ.POLLIN)
      };
      //  If we have no workers anyhow, wait indefinitely
      int rc = ZMQ.poll(primary, local_capacity > 0 ? 1000 : -1);
      if (rc == -1) break; //  Interrupted

      //  Track if capacity changes during this iteration
      int previous = local_capacity;

      //  Handle reply from local worker
      ZMsg msg = null;
      if (primary[0].isReadable()) {
        msg = ZMsg.recvMsg(localbe);
        if (msg == null) break; //  Interrupted
        ZFrame address = msg.unwrap();
        workers.add(address);
        local_capacity++;

        //  If it's READY, don't route the message any further
        ZFrame frame = msg.getFirst();
        if (new String(frame.getData()).equals(LRU_READY)) {
          msg.destroy();
          msg = null;
        }
      }
      //  Or handle reply from peer broker
      else if (primary[1].isReadable()) {
        msg = ZMsg.recvMsg(cloudbe);
        if (msg == null) break; //  Interrupted
        //  We don't use peer broker address for anything
        ZFrame address = msg.unwrap();
        address.destroy();
        System.out.println("Recv from cloudbe");
      }
      //  Route reply to cloud if it's addressed to a broker
      for (argn = 1; msg != null && argn < argv.length; argn++) {
        byte[] data = msg.getFirst().data();
        if (argv[argn].equals(new String(data))) {
          msg.send(cloudfe);
          msg = null;
        }
      }
      //  Route reply to client if we still need to
      if (msg != null) msg.send(localfe);

      //  If we have input messages on our statefe or monitor sockets we
      //  can process these immediately:

      if (primary[2].isReadable()) {
        String peer = statefe.recvStr();
        String status = statefe.recvStr();
        cloud_capacity = Integer.parseInt(status);
      }
      if (primary[3].isReadable()) {
        String status = monitor.recvStr();
        System.out.println(String.format("%s\n", status));
      }

      //  Now we route as many client requests as we have worker capacity
      //  for. We may reroute requests from our local frontend, but not from //
      //  the cloud frontend. We reroute randomly now, just to test things
      //  out. In the next version we'll do this properly by calculating
      //  cloud capacity://

      while (local_capacity + cloud_capacity > 0) {
        PollItem secondary[] = {
          new PollItem(localfe, ZMQ.POLLIN), new PollItem(cloudfe, ZMQ.POLLIN)
        };

        if (local_capacity == 0) secondary[1].interestOps(0);

        rc = ZMQ.poll(secondary, 0);
        assert (rc >= 0);

        if (secondary[0].isReadable()) {
          msg = ZMsg.recvMsg(localfe);
        } else if (secondary[1].isReadable()) {
          msg = ZMsg.recvMsg(cloudfe);
        } else break; //  No work, go back to backends

        if (local_capacity > 0) {
          ZFrame frame = workers.remove(0);
          msg.wrap(frame);
          msg.send(localbe);
          local_capacity--;

        } else {
          //  Route to random broker peer
          int random_peer = rand.nextInt(argv.length - 1) + 1;
          msg.push(argv[random_peer]);
          msg.send(cloudbe);
          System.out.println("Sent to cloudbe " + argv[random_peer]);
        }
      }

      //  We broadcast capacity messages to other peers; to reduce chatter
      //  we do this only if our capacity changed.

      if (local_capacity != previous) {
        //  We stick our own address onto the envelope
        statebe.sendMore(self);
        //  Broadcast new capacity
        statebe.send(String.format("%d", local_capacity), 0);
        System.out.println("Sent to statebe " + local_capacity);
      }
    }
    //  When we're done, clean up properly
    while (workers.size() > 0) {
      ZFrame frame = workers.remove(0);
      frame.destroy();
    }

    ctx.destroy();
  }