/*
 * Copyright 2016 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.channel;

import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.FutureListener;

import java.net.ConnectException;
import java.net.SocketAddress;

public interface ChannelOutboundInvoker {

    
Request to bind to the given SocketAddress and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error.

This will result in having the ChannelOutboundHandler.bind(ChannelHandlerContext, SocketAddress, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation * completes, either because the operation was successful or because of an error. * <p> * This will result in having the * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture bind(SocketAddress localAddress);
Request to connect to the given SocketAddress and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error.

If the connection fails because of a connection timeout, the ChannelFuture will get failed with a ConnectTimeoutException. If it fails because of connection refused a ConnectException will be used.

This will result in having the ChannelOutboundHandler.connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation * completes, either because the operation was successful or because of an error. * <p> * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} * will be used. * <p> * This will result in having the * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture connect(SocketAddress remoteAddress);
Request to connect to the given SocketAddress while bind to the localAddress and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error.

This will result in having the ChannelOutboundHandler.connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of * an error. * <p> * This will result in having the * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
Request to disconnect from the remote peer and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error.

This will result in having the ChannelOutboundHandler.disconnect(ChannelHandlerContext, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, * either because the operation was successful or because of an error. * <p> * This will result in having the * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture disconnect();
Request to close the Channel and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. After it is closed it is not possible to reuse it again.

This will result in having the ChannelOutboundHandler.close(ChannelHandlerContext, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, * either because the operation was successful or because of * an error. * * After it is closed it is not possible to reuse it again. * <p> * This will result in having the * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture close();
Request to deregister from the previous assigned EventExecutor and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error.

This will result in having the ChannelOutboundHandler.deregister(ChannelHandlerContext, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to deregister from the previous assigned {@link EventExecutor} and notify the * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of * an error. * <p> * This will result in having the * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. * */
ChannelFuture deregister();
Request to bind to the given SocketAddress and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. The given ChannelPromise will be notified.

This will result in having the ChannelOutboundHandler.bind(ChannelHandlerContext, SocketAddress, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation * completes, either because the operation was successful or because of an error. * * The given {@link ChannelPromise} will be notified. * <p> * This will result in having the * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
Request to connect to the given SocketAddress and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. The given ChannelFuture will be notified.

If the connection fails because of a connection timeout, the ChannelFuture will get failed with a ConnectTimeoutException. If it fails because of connection refused a ConnectException will be used.

This will result in having the ChannelOutboundHandler.connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation * completes, either because the operation was successful or because of an error. * * The given {@link ChannelFuture} will be notified. * * <p> * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} * will be used. * <p> * This will result in having the * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
Request to connect to the given SocketAddress while bind to the localAddress and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. The given ChannelPromise will be notified and also returned.

This will result in having the ChannelOutboundHandler.connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of * an error. * * The given {@link ChannelPromise} will be notified and also returned. * <p> * This will result in having the * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
Request to disconnect from the remote peer and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. The given ChannelPromise will be notified.

This will result in having the ChannelOutboundHandler.disconnect(ChannelHandlerContext, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, * either because the operation was successful or because of an error. * * The given {@link ChannelPromise} will be notified. * <p> * This will result in having the * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture disconnect(ChannelPromise promise);
Request to close the Channel and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. After it is closed it is not possible to reuse it again. The given ChannelPromise will be notified.

This will result in having the ChannelOutboundHandler.close(ChannelHandlerContext, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, * either because the operation was successful or because of * an error. * * After it is closed it is not possible to reuse it again. * The given {@link ChannelPromise} will be notified. * <p> * This will result in having the * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture close(ChannelPromise promise);
Request to deregister from the previous assigned EventExecutor and notify the ChannelFuture once the operation completes, either because the operation was successful or because of an error. The given ChannelPromise will be notified.

This will result in having the ChannelOutboundHandler.deregister(ChannelHandlerContext, ChannelPromise) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to deregister from the previous assigned {@link EventExecutor} and notify the * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of * an error. * * The given {@link ChannelPromise} will be notified. * <p> * This will result in having the * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelFuture deregister(ChannelPromise promise);
Request to Read data from the Channel into the first inbound buffer, triggers an ChannelInboundHandler.channelRead(ChannelHandlerContext, Object) event if data was read, and triggers a channelReadComplete event so the handler can decide to continue reading. If there's a pending read operation already, this method does nothing.

This will result in having the ChannelOutboundHandler.read(ChannelHandlerContext) method called of the next ChannelOutboundHandler contained in the ChannelPipeline of the Channel.

/** * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was * read, and triggers a * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the * handler can decide to continue reading. If there's a pending read operation already, this method does nothing. * <p> * This will result in having the * {@link ChannelOutboundHandler#read(ChannelHandlerContext)} * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the * {@link Channel}. */
ChannelOutboundInvoker read();
Request to write a message via this ChannelHandlerContext through the ChannelPipeline. This method will not request to actual flush, so be sure to call flush() once you want to request to flush all pending data to the actual transport.
/** * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. * This method will not request to actual flush, so be sure to call {@link #flush()} * once you want to request to flush all pending data to the actual transport. */
ChannelFuture write(Object msg);
Request to write a message via this ChannelHandlerContext through the ChannelPipeline. This method will not request to actual flush, so be sure to call flush() once you want to request to flush all pending data to the actual transport.
/** * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. * This method will not request to actual flush, so be sure to call {@link #flush()} * once you want to request to flush all pending data to the actual transport. */
ChannelFuture write(Object msg, ChannelPromise promise);
Request to flush all pending messages via this ChannelOutboundInvoker.
/** * Request to flush all pending messages via this ChannelOutboundInvoker. */
ChannelOutboundInvoker flush();
Shortcut for call write(Object, ChannelPromise) and flush().
/** * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}. */
ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
Shortcut for call write(Object) and flush().
/** * Shortcut for call {@link #write(Object)} and {@link #flush()}. */
ChannelFuture writeAndFlush(Object msg);
Return a new ChannelPromise.
/** * Return a new {@link ChannelPromise}. */
ChannelPromise newPromise(); /** * Return an new {@link ChannelProgressivePromise} */ ChannelProgressivePromise newProgressivePromise();
Create a new ChannelFuture which is marked as succeeded already. So Future<Void>.isSuccess() will return true. All FutureListener added to it will be notified directly. Also every call of blocking methods will just return without blocking.
/** * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()} * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also * every call of blocking methods will just return without blocking. */
ChannelFuture newSucceededFuture();
Create a new ChannelFuture which is marked as failed already. So Future<Void>.isSuccess() will return false. All FutureListener added to it will be notified directly. Also every call of blocking methods will just return without blocking.
/** * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()} * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also * every call of blocking methods will just return without blocking. */
ChannelFuture newFailedFuture(Throwable cause);
Return a special ChannelPromise which can be reused for different operations.

It's only supported to use it for write(Object, ChannelPromise).

Be aware that the returned ChannelPromise will not support most operations and should only be used if you want to save an object allocation for every write operation. You will not be able to detect if the operation was complete, only if it failed as the implementation will call ChannelPipeline.fireExceptionCaught(Throwable) in this case.

Be aware this is an expert feature and should be used with care!
/** * Return a special ChannelPromise which can be reused for different operations. * <p> * It's only supported to use * it for {@link ChannelOutboundInvoker#write(Object, ChannelPromise)}. * </p> * <p> * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used * if you want to save an object allocation for every write operation. You will not be able to detect if the * operation was complete, only if it failed as the implementation will call * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case. * </p> * <strong>Be aware this is an expert feature and should be used with care!</strong> */
ChannelPromise voidPromise(); }