Can I interrupt a worker thread?

Nitrostar nitrostar1 at gmail.com
Sat Aug 14 16:24:27 EDT 2010


I was thinking about something like:

import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static
org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static
org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.util.CharsetUtil;
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.Timer;
import org.jboss.netty.util.TimerTask;

public class ServerHandler extends SimpleChannelUpstreamHandler {

    private HttpRequest request;
    private final StringBuilder buf = new StringBuilder();
    private Timer timer;
    private Timeout respondTimeout;
    private AtomicBoolean sentResponse = new AtomicBoolean(false);
    private Thread finalThread;

    public ServerHandler(Timer timer){
        this.timer = timer;
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
        finalThread = Thread.currentThread();
        respondTimeout = timer.newTimeout(new RespondTimeoutTask(e), 100,
TimeUnit.MILLISECONDS);
        HttpRequest request = this.request = (HttpRequest) e.getMessage();
        buf.setLength(0);

        // THIS CAN POTENTIALLY TAKE A LONG PROCESSING TIME
        String response = doSomething();
        buf.append(response);

        setResponse(e);
    }

    private void setResponse(MessageEvent e) {
        // Decide whether to close the connection or not.
        boolean keepAlive = isKeepAlive(request);

        // Build the response object.
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        response.setContent(ChannelBuffers.copiedBuffer(buf.toString(),
CharsetUtil.UTF_8));
        response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");

        if (keepAlive) {
            // Add 'Content-Length' header only for a keep-alive connection.
            response.setHeader(CONTENT_LENGTH,
response.getContent().readableBytes());
        }

        // Write the response 
        writeResponse(e.getChannel(), response, !keepAlive);
    }
    
    public void writeResponse(Channel ch, HttpResponse response, boolean
close){
        if(!sentResponse.compareAndSet(false, true)){
            return;
        }
        respondTimeout.cancel();
        ChannelFuture future = ch.write(response);
        if(close){
            future.addListener(ChannelFutureListener.CLOSE);
        }
        
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception{
        e.getCause().printStackTrace();
        e.getChannel().close();
    }

    private final class RespondTimeoutTask implements TimerTask {
        MessageEvent e;

        public RespondTimeoutTask(MessageEvent e){
            this.e = e;
        }

        public void run(Timeout timeout) throws Exception {
            if (timeout.isCancelled()) {
                return;
            }
            if(!sentResponse.compareAndSet(false, true)){
                return;
            }
            try{
                finalThread.interrupt();
            } catch(SecurityException e){
                
            }

            // Build the response object.
            HttpResponse response = new DefaultHttpResponse(HTTP_1_1,
HttpResponseStatus.INTERNAL_SERVER_ERROR);
            response.setContent(ChannelBuffers.copiedBuffer("Sorry but we
timed out", CharsetUtil.UTF_8));
            response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");

            // Write the response.
            writeResponse(e.getChannel(), response, true);
        }
    }
}


-- 
View this message in context: http://netty-forums-and-mailing-lists.685743.n2.nabble.com/Can-I-interrupt-a-worker-thread-tp5422043p5424002.html
Sent from the Netty User Group mailing list archive at Nabble.com.


More information about the netty-users mailing list