class RemotingContext {

    private ChannelHandlerContext                       channelContext;

    private boolean                                     serverSide     = false;

    /** whether need handle request timeout, if true, request will be discarded. The default value is true */
    private boolean                                     timeoutDiscard = true;

    /** request arrive time stamp */
    private long                                        arriveTimestamp;

    /** request timeout setting by invoke side */
    private int                                         timeout;

    /** rpc command type */
    private int                                         rpcCommandType;

    private ConcurrentHashMap<String, UserProcessor<?>> userProcessors;

    private InvokeContext                               invokeContext;

    /**
     * Constructor.
     * 
     * @param ctx
     */
    public RemotingContext(ChannelHandlerContext ctx) {
        this.channelContext = ctx;
    }

    /**
     * Constructor.
     * @param ctx
     * @param serverSide
     */
    public RemotingContext(ChannelHandlerContext ctx, boolean serverSide) {
        this.channelContext = ctx;
        this.serverSide = serverSide;
    }

    /**
     * Constructor.
     * @param ctx
     * @param serverSide
     * @param userProcessors
     */
    public RemotingContext(ChannelHandlerContext ctx, boolean serverSide,
                           ConcurrentHashMap<String, UserProcessor<?>> userProcessors) {
        this.channelContext = ctx;
        this.serverSide = serverSide;
        this.userProcessors = userProcessors;
    }

    /**
     * Constructor.
     * @param ctx
     * @param invokeContext
     * @param serverSide
     * @param userProcessors
     */
    public RemotingContext(ChannelHandlerContext ctx, InvokeContext invokeContext,
                           boolean serverSide,
                           ConcurrentHashMap<String, UserProcessor<?>> userProcessors) {
        this.channelContext = ctx;
        this.serverSide = serverSide;
        this.userProcessors = userProcessors;
        this.invokeContext = invokeContext;
    }

    /**
     * Wrap the writeAndFlush method.
     * 
     * @param msg as msg
     * @return channel future
     */
    public ChannelFuture writeAndFlush(RemotingCommand msg) {
        return this.channelContext.writeAndFlush(msg);
    }

    /**
     * Wrap the write method.
     *
     * @param msg as msg
     * @return channel future
     */
    public ChannelFuture write(RemotingCommand msg) {
        return this.channelContext.write(msg);
    }

    /**
     * Wrap the write method.
     *
     */
    public void flush() {
        this.channelContext.flush();
    }

    /**
     * whether this request already timeout
     * 
     * @return
     */
    public boolean isRequestTimeout() {<FILL_FUNCTION_BODY>}

    /**
     * The server side
     * 
     * @return
     */
    public boolean isServerSide() {
        return this.serverSide;
    }

    /** 
     * Get user processor for class name.
     * 
     * @param className
     * @return
     */
    public UserProcessor<?> getUserProcessor(String className) {
        return StringUtils.isBlank(className) ? null : this.userProcessors.get(className);
    }

    /**
     * Get connection from channel
     * 
     * @return
     */
    public Connection getConnection() {
        return ConnectionUtil.getConnectionFromChannel(channelContext.channel());
    }

    /**
     * Get the channel handler context.
     *
     * @return
     */
    public ChannelHandlerContext getChannelContext() {
        return channelContext;
    }

    /**
     * Set the channel handler context.
     *
     * @param ctx
     */
    public void setChannelContext(ChannelHandlerContext ctx) {
        this.channelContext = ctx;
    }

    /**
     * Getter method for property <tt>invokeContext</tt>.
     *
     * @return property value of invokeContext
     */
    public InvokeContext getInvokeContext() {
        return invokeContext;
    }

    /**
     * Setter method for property <tt>arriveTimestamp<tt>.
     *
     * @param arriveTimestamp value to be assigned to property arriveTimestamp
     */
    public void setArriveTimestamp(long arriveTimestamp) {
        this.arriveTimestamp = arriveTimestamp;
    }

    /**
     * Getter method for property <tt>arriveTimestamp</tt>.
     *
     * @return property value of arriveTimestamp
     */
    public long getArriveTimestamp() {
        return arriveTimestamp;
    }

    /**
     * Setter method for property <tt>timeout<tt>.
     *
     * @param timeout value to be assigned to property timeout
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /**
     * Getter method for property <tt>timeout</tt>.
     *
     * @return property value of timeout
     */
    public int getTimeout() {
        return timeout;
    }

    /**
     * Setter method for property <tt>rpcCommandType<tt>.
     *
     * @param rpcCommandType value to be assigned to property rpcCommandType
     */
    public void setRpcCommandType(int rpcCommandType) {
        this.rpcCommandType = rpcCommandType;
    }

    public boolean isTimeoutDiscard() {
        return timeoutDiscard;
    }

    public RemotingContext setTimeoutDiscard(boolean failFastEnabled) {
        this.timeoutDiscard = failFastEnabled;
        return this;
    }
}

        if (this.timeout > 0 && (this.rpcCommandType != RpcCommandType.REQUEST_ONEWAY)
            && (System.currentTimeMillis() - this.arriveTimestamp) > this.timeout) {
            return true;
        }
        return false;
    
<no_super_class>