Example #1
0
  @Override
  public Promise<Void> shutdown() {
    final Deferred<Void, Promise<Void>> d = Promises.defer(env, getReactor().getDispatcher());
    Reactors.schedule(
        new Consumer<Void>() {
          @SuppressWarnings({"rawtypes", "unchecked"})
          @Override
          public void accept(Void v) {
            final AtomicInteger groupsToShutdown = new AtomicInteger(2);
            GenericFutureListener listener =
                new GenericFutureListener() {

                  @Override
                  public void operationComplete(Future future) throws Exception {
                    if (groupsToShutdown.decrementAndGet() == 0) {
                      notifyShutdown();
                      d.accept((Void) null);
                    }
                  }
                };
            selectorGroup.shutdownGracefully().addListener(listener);
            ioGroup.shutdownGracefully().addListener(listener);
          }
        },
        null,
        getReactor());

    return d.compose();
  }
  private void multipleRingBufferDispatchers() {
    Boundary b = new Boundary();

    Reactor r1 = Reactors.reactor().env(env).dispatcher(Environment.RING_BUFFER).get();
    Reactor r2 = Reactors.reactor().env(env).dispatcher(Environment.RING_BUFFER).get();

    // Bind to a Selector using an anonymous object
    Tuple2<Selector, Object> anon = $();

    r1.on(anon.getT1(), b.bind(consumer, 3));
    r2.on(anon.getT1(), b.bind(consumer, 2));

    r1.notify(anon.getT2(), Event.wrap(r1));
    r1.notify(anon.getT2(), Event.wrap(r1));
    r1.notify(anon.getT2(), Event.wrap(r1));

    r2.notify(anon.getT2(), Event.wrap(r2));
    r2.notify(anon.getT2(), Event.wrap(r2));

    b.await();
  }
Example #3
0
  @Test
  public void workerOrchestrator() throws InterruptedException {
    Reactor reactor = Reactors.reactor(env, Environment.WORK_QUEUE);

    CountDownLatch latch = new CountDownLatch(3);

    reactor.on(
        Selectors.$("worker"),
        new Consumer() {
          @Override
          public void accept(Object o) {
            System.out.println(Thread.currentThread().getName() + " worker " + o);
            reactor.notify("orchestrator", Event.wrap(1000));
            latch.countDown();
            System.out.println(Thread.currentThread().getName() + " ok");
          }
        });

    reactor.on(
        Selectors.$("orchestrator"),
        new Consumer<Event<Integer>>() {

          @Override
          public void accept(Event<Integer> event) {
            sendTask();
          }

          void sendTask() {
            System.out.println(Thread.currentThread().getName() + " sendTask ");
            reactor.notify("worker", Event.wrap(latch.getCount()));
            latch.countDown();
          }
        });

    reactor.notify("orchestrator", Event.wrap(1000));

    Assert.isTrue(latch.await(10, TimeUnit.SECONDS));
  }
 @Bean
 public Reactor threadPoolReactor(Environment env) {
   return Reactors.reactor().env(env).dispatcher(Environment.THREAD_POOL).get();
 }
  public static void main(String[] args) throws Exception {
    Environment env = new Environment();
    final TradeServer server = new TradeServer();

    // Use a Reactor to dispatch events using the high-speed Dispatcher
    final Reactor serverReactor = Reactors.reactor(env);

    // Create a single key and Selector for efficiency
    final Selector tradeExecute = Selectors.object("trade.execute");

    // For each Trade event, execute that on the server and notify connected clients
    // because each client that connects links to the serverReactor
    serverReactor.on(
        tradeExecute,
        (Event<Trade> ev) -> {
          server.execute(ev.getData());

          // Since we're async, for this test, use a latch to tell when we're done
          latch.countDown();
        });

    @SuppressWarnings("serial")
    WebSocketServlet wss =
        new WebSocketServlet() {
          @Override
          public void configure(WebSocketServletFactory factory) {
            factory.setCreator(
                (req, resp) ->
                    new WebSocketListener() {
                      AtomicLong counter = new AtomicLong();

                      @Override
                      public void onWebSocketBinary(byte[] payload, int offset, int len) {}

                      @Override
                      public void onWebSocketClose(int statusCode, String reason) {}

                      @Override
                      public void onWebSocketConnect(final Session session) {
                        LOG.info("Connected a websocket client: {}", session);

                        // Keep track of a rolling average
                        final AtomicReference<Float> avg = new AtomicReference<>(0f);

                        serverReactor.on(
                            tradeExecute,
                            (Event<Trade> ev) -> {
                              Trade t = ev.getData();
                              avg.set((avg.get() + t.getPrice()) / 2);

                              // Send a message every 1000th trade.
                              // Otherwise, we completely overwhelm the browser and network.
                              if (counter.incrementAndGet() % 1000 == 0) {
                                try {
                                  session
                                      .getRemote()
                                      .sendString(String.format("avg: %s", avg.get()));
                                } catch (IOException e) {
                                  if (!"Failed to write bytes".equals(e.getMessage())) {
                                    e.printStackTrace();
                                  }
                                }
                              }
                            });
                      }

                      @Override
                      public void onWebSocketError(Throwable cause) {}

                      @Override
                      public void onWebSocketText(String message) {}
                    });
          }
        };
    serve(wss);

    LOG.info(
        "Connect websocket clients now (waiting for 10 seconds).\n"
            + "Open websocket/src/main/webapp/ws.html in a browser...");
    Thread.sleep(10000);

    // Start a throughput timer
    startTimer();

    // Publish one event per trade
    for (int i = 0; i < totalTrades; i++) {
      // Pull next randomly-generated Trade from server
      Trade t = server.nextTrade();

      // Notify the Reactor the event is ready to be handled
      serverReactor.notify(tradeExecute.getObject(), Event.wrap(t));
    }

    // Stop throughput timer and output metrics
    endTimer();

    server.stop();
  }