/** * Send data on this connection. The current codec (if any) will be used to encode the data to a {@link * reactor.io.Buffer}. The given callback will be invoked when the write has completed. * * @param data * The outgoing data. * @param onComplete * The callback to invoke when the write is complete. */ protected void send(OUT data, final Deferred<Void, Promise<Void>> onComplete) { Reactors.schedule(new WriteConsumer(onComplete), data, ioReactor); }
@Override public Promise<T> consumeFlush(Flushable<?> action) { lock.lock(); try { if (state != State.PENDING) { Reactors.schedule( new FlushableAction(action, null, null), Flushable.FLUSH_EVENT, getObservable()); } else { super.consumeFlush(action); } return this; } finally { lock.unlock(); } }
@Override @SuppressWarnings("unchecked") public <E extends Throwable> Promise<T> when(@Nonnull Class<E> exceptionType, @Nonnull Consumer<E> onError) { lock.lock(); try { if (state == State.FAILURE) { Reactors.schedule( new CallbackAction<E>(onError, getObservable(), null), Event.wrap((E) error), getObservable()); } else { super.when(exceptionType, onError); } return this; } finally { lock.unlock(); } }
@Override public Promise<T> add(Action<T> operation) { lock.lock(); try { if (state == State.SUCCESS) { Reactors.schedule(operation, Event.wrap(value), getObservable()); } else if (state == State.FAILURE) { Reactors.schedule( new ConnectAction<Throwable>(operation.getObservable(), operation.getFailureKey(), null), Event.wrap(error), getObservable()); } else { super.add(operation); } return this; } finally { lock.unlock(); } }
/** * Close any open connections and disconnect this client. * * @return A {@link Promise} that will be fulfilled with {@literal null} when the connections have been closed. */ public Promise<Void> close() { final Deferred<Void, Promise<Void>> d = Promises.defer(env, reactor.getDispatcher()); Reactors.schedule( new Consumer<Void>() { @SuppressWarnings("ConstantConditions") @Override public void accept(Void v) { for(Map.Entry<Object, WeakReference<TcpConnection<IN, OUT>>> entry : connections.entrySet()) { if(null != entry.getValue().get()) { entry.getValue().get().close(); } } doClose(d); } }, null, reactor ); return d.compose(); }
/** * Assign a {@link Consumer} that will either be invoked later, when the {@code Promise} is completed by either * setting a value or propagating an error, or, if this {@code Promise} has already been fulfilled, is immediately * scheduled to be executed on the current {@link reactor.event.dispatch.Dispatcher}. * * @param onComplete the completion {@link Consumer} * @return {@literal this} */ public Promise<T> onComplete(@Nonnull final Consumer<Promise<T>> onComplete) { if (isComplete()) { Reactors.schedule(onComplete, this, getObservable()); } else { getObservable().on(getFlush(), new CallbackAction<Promise<T>>(onComplete, getObservable(), null)); } return this; }
@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(); }