@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); } }
@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; }
@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; }
@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)); }
/** * 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); }