@SuppressWarnings("unchecked")
  public <E> void dispatch(
      Object key,
      E event,
      Registry<Consumer<?>> consumerRegistry,
      Consumer<Throwable> errorConsumer,
      Router router,
      Consumer<E> completionConsumer,
      boolean isInContext) {
    Assert.isTrue(alive(), "This Dispatcher has been shut down.");

    try {
      Task task;
      if (isInContext) {
        task = allocateRecursiveTask();
      } else {
        task = allocateTask();
      }

      task.setKey(key)
          .setData(event)
          .setConsumerRegistry(consumerRegistry)
          .setErrorConsumer(errorConsumer)
          .setRouter(router);

      if (completionConsumer != null)
        task.setCompletionConsumer((Consumer<Object>) completionConsumer);

      if (!isInContext) {
        execute(task);
      }
    } catch (Exception e) {
      throw new IllegalStateException(e.getMessage() + " " + Thread.currentThread(), e);
    }
  }
Beispiel #2
0
 protected Composable(
     @Nullable Environment env, @Nonnull Observable events, @Nullable Composable parent) {
   Assert.notNull(events, "Events Observable cannot be null.");
   this.env = env;
   this.events = events;
   this.parent = parent;
 }
Beispiel #3
0
 /**
  * Close the given channel.
  *
  * @param channel The channel object.
  * @param <C> The type of the channel object.
  */
 protected <C> void close(@Nonnull C channel) {
   Assert.notNull(channel, "Channel cannot be null");
   for (Registration<? extends NetChannel<IN, OUT>> reg : netChannels.select(channel)) {
     NetChannel<IN, OUT> chann = reg.getObject();
     reg.cancel();
     notifyClose(chann);
   }
 }
Beispiel #4
0
 /**
  * Find the {@link NetChannel} for the given IO channel object.
  *
  * @param ioChannel The channel object.
  * @param <C> The type of the channel object.
  * @return The {@link NetChannel} associated with the given channel.
  */
 protected <C> NetChannel<IN, OUT> select(@Nonnull C ioChannel) {
   Assert.notNull(ioChannel, "Channel cannot be null.");
   Iterator<Registration<? extends NetChannel<IN, OUT>>> channs =
       netChannels.select(ioChannel).iterator();
   if (channs.hasNext()) {
     return channs.next().getObject();
   } else {
     NetChannel<IN, OUT> conn = createChannel(ioChannel);
     register(ioChannel, conn);
     notifyOpen(conn);
     return conn;
   }
 }
Beispiel #5
0
 /**
  * Assign the given {@link Function} to transform the incoming value {@code T} into a {@code V}
  * and pass it into another {@code Composable}.
  *
  * @param fn the transformation function
  * @param <V> the type of the return value of the transformation function
  * @return a new {@code Composable} containing the transformed values
  */
 public <V> Composable<V> map(@Nonnull final Function<T, V> fn) {
   Assert.notNull(fn, "Map function cannot be null.");
   final Deferred<V, ? extends Composable<V>> d = createDeferred();
   consume(
       new Consumer<T>() {
         @Override
         public void accept(T value) {
           try {
             V val = fn.apply(value);
             d.accept(val);
           } catch (Throwable e) {
             d.accept(e);
           }
         }
       });
   return d.compose();
 }
 @SuppressWarnings("unchecked")
 @Override
 public <V> StateMachine<T> notify(final V state, final T value) {
   if (strict) {
     Assert.isTrue(states.contains(state), "State " + state + " has not been defined");
   }
   Event<T> ev = Event.wrap(value instanceof Event ? ((Event<T>) value).getData() : value);
   observable.notify(
       state,
       ev,
       new Consumer<Event<T>>() {
         @Override
         public void accept(final Event<T> ev) {
           transition(state, ev.getData());
         }
       });
   return this;
 }
Beispiel #7
0
  /**
   * Slice this buffer at the given positions. Useful for extracting multiple segments of data from
   * a buffer when the exact indices of that data is already known.
   *
   * @param positions The start and end positions of the slices.
   * @return A list of {@link View Views} pointing to the slices.
   */
  public List<View> slice(int... positions) {
    Assert.notNull(positions, "Positions cannot be null.");
    if (positions.length == 0) {
      return Collections.emptyList();
    }

    snapshot();

    List<View> views = new ArrayList<View>();
    int len = positions.length;
    for (int i = 0; i < len; i++) {
      int start = positions[i];
      int end = (i + 1 < len ? positions[++i] : this.limit);
      views.add(createView(start, end));
      reset();
    }

    return views;
  }
Beispiel #8
0
 /**
  * Evaluate each accepted value against the given {@link Predicate}. If the predicate test
  * succeeds, the value is passed into the new {@code Composable}. If the predicate test fails, an
  * exception is propagated into the new {@code Composable}.
  *
  * @param p the {@link Predicate} to test values against
  * @return a new {@code Composable} containing only values that pass the predicate test
  */
 public Composable<T> filter(@Nonnull final Predicate<T> p) {
   Assert.notNull(p, "Filter predicate cannot be null.");
   final Deferred<T, ? extends Composable<T>> d = createDeferred();
   consume(
       new Consumer<T>() {
         @Override
         public void accept(T value) {
           boolean b = p.test(value);
           if (b) {
             d.accept(value);
           } else {
             d.accept(
                 new IllegalArgumentException(
                     String.format("%s failed a predicate test.", value)));
           }
         }
       });
   return d.compose();
 }
Beispiel #9
0
 /**
  * Create a {@code TcpClient.Spec} using the given implementation class.
  *
  * @param clientImpl The concrete implementation of {@link TcpClient} to instantiate.
  */
 @SuppressWarnings({"unchecked", "rawtypes"})
 public TcpClientSpec(@Nonnull Class<? extends TcpClient> clientImpl) {
   Assert.notNull(clientImpl, "TcpClient implementation class cannot be null.");
   try {
     this.clientImplConstructor =
         (Constructor<TcpClient<IN, OUT>>)
             clientImpl.getDeclaredConstructor(
                 Environment.class,
                 Reactor.class,
                 InetSocketAddress.class,
                 ClientSocketOptions.class,
                 SslOptions.class,
                 Codec.class,
                 Collection.class);
     this.clientImplConstructor.setAccessible(true);
   } catch (NoSuchMethodException e) {
     throw new IllegalArgumentException(
         "No public constructor found that matches the signature of the one found in the TcpClient class.");
   }
 }
 @Override
 public <V> StateMachine<T> on(final V state, final Function<T, T> fn) {
   if (strict) {
     Assert.isTrue(states.contains(state), "State " + state + " has not been defined");
   }
   observable.on(
       (state instanceof Selector ? (Selector) state : Selectors.object(state)),
       new Consumer<Event<T>>() {
         @SuppressWarnings("unchecked")
         @Override
         public void accept(final Event<T> data) {
           try {
             data.setData(fn.apply(data.getData()));
           } catch (Throwable t) {
             observable.notify(
                 t.getClass(), Event.wrap(new StateException(t, state, data.getData())));
           }
         }
       });
   return this;
 }
Beispiel #11
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));
  }
Beispiel #12
0
 /**
  * Allow interceptors etc to publish events, perhaps subclasses of TcpConnectionEvent. The event
  * source must be this connection.
  *
  * @param event the event to publish.
  */
 public void publishEvent(TcpConnectionEvent event) {
   Assert.isTrue(event.getData() == this, "Can only publish events with this as the source");
   this.doPublish(event);
 }
Beispiel #13
0
  protected NettyTcpServer(
      Environment env,
      Reactor reactor,
      InetSocketAddress listenAddress,
      final ServerSocketOptions opts,
      final SslOptions sslOpts,
      Codec<Buffer, IN, OUT> codec,
      Collection<Consumer<TcpConnection<IN, OUT>>> connectionConsumers) {
    super(env, reactor, listenAddress, opts, sslOpts, codec, connectionConsumers);
    this.eventsReactor = reactor;
    this.listenAddress = listenAddress;
    Assert.notNull(opts, "ServerSocketOptions cannot be null");
    this.options = opts;

    int selectThreadCount =
        env.getProperty("reactor.tcp.selectThreadCount", Integer.class, Environment.PROCESSORS / 2);
    int ioThreadCount =
        env.getProperty("reactor.tcp.ioThreadCount", Integer.class, Environment.PROCESSORS);
    selectorGroup =
        new NioEventLoopGroup(
            selectThreadCount, new NamedDaemonThreadFactory("reactor-tcp-select"));
    ioGroup = new NioEventLoopGroup(ioThreadCount, new NamedDaemonThreadFactory("reactor-tcp-io"));

    this.bootstrap =
        new ServerBootstrap()
            .group(selectorGroup, ioGroup)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, options.backlog())
            .option(ChannelOption.SO_RCVBUF, options.rcvbuf())
            .option(ChannelOption.SO_SNDBUF, options.sndbuf())
            .option(ChannelOption.SO_REUSEADDR, options.reuseAddr())
            .localAddress((null == listenAddress ? new InetSocketAddress(3000) : listenAddress))
            .childHandler(
                new ChannelInitializer<SocketChannel>() {
                  @Override
                  public void initChannel(final SocketChannel ch) throws Exception {
                    SocketChannelConfig config = ch.config();
                    config.setReceiveBufferSize(options.rcvbuf());
                    config.setSendBufferSize(options.sndbuf());
                    config.setKeepAlive(options.keepAlive());
                    config.setReuseAddress(options.reuseAddr());
                    config.setSoLinger(options.linger());
                    config.setTcpNoDelay(options.tcpNoDelay());

                    if (log.isDebugEnabled()) {
                      log.debug("CONNECT {}", ch);
                    }

                    if (null != sslOpts) {
                      SSLEngine ssl = new SSLEngineSupplier(sslOpts, false).get();
                      if (log.isDebugEnabled()) {
                        log.debug(
                            "SSL enabled using keystore {}",
                            (null != sslOpts.keystoreFile()
                                ? sslOpts.keystoreFile()
                                : "<DEFAULT>"));
                      }
                      ch.pipeline().addLast(new SslHandler(ssl));
                    }
                    if (options instanceof NettyServerSocketOptions
                        && null != ((NettyServerSocketOptions) options).pipelineConfigurer()) {
                      ((NettyServerSocketOptions) options)
                          .pipelineConfigurer()
                          .accept(ch.pipeline());
                    }
                    ch.pipeline().addLast(createChannelHandlers(ch));
                    ch.closeFuture()
                        .addListener(
                            new ChannelFutureListener() {
                              @Override
                              public void operationComplete(ChannelFuture future) throws Exception {
                                if (log.isDebugEnabled()) {
                                  log.debug("CLOSE {}", ch);
                                }
                                close(ch);
                              }
                            });
                  }
                });
  }
Beispiel #14
0
 /**
  * Subclasses should register the given {@link reactor.net.NetChannel} for later use.
  *
  * @param ioChannel The channel object.
  * @param netChannel The {@link NetChannel}.
  * @param <C> The type of the channel object.
  * @return {@link reactor.event.registry.Registration} of this channel in the {@link Registry}.
  */
 protected <C> Registration<? extends NetChannel<IN, OUT>> register(
     @Nonnull C ioChannel, @Nonnull NetChannel<IN, OUT> netChannel) {
   Assert.notNull(ioChannel, "Channel cannot be null.");
   Assert.notNull(netChannel, "NetChannel cannot be null.");
   return netChannels.register(Selectors.$(ioChannel), netChannel);
 }
Beispiel #15
0
 /**
  * Notify this client's consumers than a global error has occurred.
  *
  * @param error The error to notify.
  */
 protected void notifyError(@Nonnull Throwable error) {
   Assert.notNull(error, "Error cannot be null.");
   reactor.notify(error.getClass(), Event.wrap(error));
 }
Beispiel #16
0
 /**
  * The address to which this client should connect.
  *
  * @param connectAddress The address to connect to.
  * @return {@literal this}
  */
 public TcpClientSpec<IN, OUT> connect(@Nonnull InetSocketAddress connectAddress) {
   Assert.isNull(this.connectAddress, "Connect address is already set.");
   this.connectAddress = connectAddress;
   return this;
 }
Beispiel #17
0
 /**
  * The {@link reactor.function.Consumer Consumers} to use to ingest the incoming data.
  *
  * @param consumers the incoming data {@link reactor.function.Consumer Consumers}
  * @return {@literal this}
  */
 public TcpClientSpec<IN, OUT> consume(Collection<Consumer<IN>> consumers) {
   Assert.notNull(consumers, "Consumers cannot be null");
   this.consumers = consumers;
   return this;
 }
Beispiel #18
0
 /**
  * The {@link Codec} to use to encode and decode data.
  *
  * @param codec The codec to use.
  * @return {@literal this}
  */
 public TcpClientSpec<IN, OUT> codec(@Nullable Codec<Buffer, IN, OUT> codec) {
   Assert.isNull(this.codec, "Codec has already been set.");
   this.codec = codec;
   return this;
 }