class ReadTimeoutTimerTask extends TimeoutTimerTask {

    private final long readTimeout;

    ReadTimeoutTimerTask(NettyResponseFuture<?> nettyResponseFuture, NettyRequestSender requestSender, TimeoutsHolder timeoutsHolder, long readTimeout) {
        super(nettyResponseFuture, requestSender, timeoutsHolder);
        this.readTimeout = readTimeout;
    }

    @Override
    public void run(Timeout timeout) {<FILL_FUNCTION_BODY>}
}

        if (done.getAndSet(true) || requestSender.isClosed()) {
            return;
        }

        if (nettyResponseFuture.isDone()) {
            timeoutsHolder.cancel();
            return;
        }

        long now = unpreciseMillisTime();

        long currentReadTimeoutInstant = readTimeout + nettyResponseFuture.getLastTouch();
        long durationBeforeCurrentReadTimeout = currentReadTimeoutInstant - now;

        if (durationBeforeCurrentReadTimeout <= 0L) {
            // idleConnectTimeout reached
            StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder().append("Read timeout to ");
            appendRemoteAddress(sb);
            String message = sb.append(" after ").append(readTimeout).append(" ms").toString();
            long durationSinceLastTouch = now - nettyResponseFuture.getLastTouch();
            expire(message, durationSinceLastTouch);
            // cancel request timeout sibling
            timeoutsHolder.cancel();

        } else {
            done.set(false);
            timeoutsHolder.startReadTimeout(this);
        }
    
<methods>public void clean() <variables>private static final Logger LOGGER,protected final java.util.concurrent.atomic.AtomicBoolean done,volatile NettyResponseFuture<?> nettyResponseFuture,protected final non-sealed org.asynchttpclient.netty.request.NettyRequestSender requestSender,final non-sealed org.asynchttpclient.netty.timeout.TimeoutsHolder timeoutsHolder