Package com.taobao.zeus.socket.worker

Source Code of com.taobao.zeus.socket.worker.WorkerHandler

package com.taobao.zeus.socket.worker;

import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;

import com.taobao.zeus.schedule.mvc.ScheduleInfoLog;
import com.taobao.zeus.socket.SocketLog;
import com.taobao.zeus.socket.protocol.Protocol.Operate;
import com.taobao.zeus.socket.protocol.Protocol.Request;
import com.taobao.zeus.socket.protocol.Protocol.Response;
import com.taobao.zeus.socket.protocol.Protocol.SocketMessage;
import com.taobao.zeus.socket.protocol.Protocol.WebResponse;
import com.taobao.zeus.socket.protocol.Protocol.SocketMessage.Kind;
import com.taobao.zeus.socket.worker.reqresp.WorkerBeCancel;
import com.taobao.zeus.socket.worker.reqresp.WorkerBeExecute;

public class WorkerHandler extends SimpleChannelUpstreamHandler{

  private CompletionService<Response> completionService=new ExecutorCompletionService<Response>(Executors.newCachedThreadPool());
  private WorkerContext context;
  public WorkerHandler(final WorkerContext context){
    this.context=context;
    context.setHandler(this);
    new Thread(){
      public void run() {
        while(true){
          try {
            Future<Response> f=completionService.take();
            Response resp=f.get();
            if(context.getServerChannel()!=null){
              context.getServerChannel().write(wapper(resp));
            }
          } catch (Exception e) {
            ScheduleInfoLog.error("take future", e);
          }
        }
      };
    }.start();
  }
  private SocketMessage wapper(Response resp){
    return SocketMessage.newBuilder().setKind(Kind.RESPONSE).setBody(resp.toByteString()).build();
  }
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
      throws Exception {
    SocketMessage sm=(SocketMessage) e.getMessage();
    if(sm.getKind()==Kind.REQUEST){
      final Request request=Request.newBuilder().mergeFrom(sm.getBody()).build();
      Operate op=request.getOperate();
      if(op==Operate.Schedule || op==Operate.Manual || op==Operate.Debug){
        completionService.submit(new Callable<Response>() {
          private WorkerBeExecute execute=new WorkerBeExecute();
          public Response call() throws Exception {
            return execute.execute(context, request).get();
          }
        });
      }else if(request.getOperate()==Operate.Cancel){
        completionService.submit(new Callable<Response>() {
          private WorkerBeCancel cancel=new WorkerBeCancel();
          public Response call() throws Exception {
            return cancel.execute(context, request).get();
          }
        });
      }
    }else if(sm.getKind()==Kind.RESPONSE){
      final Response resp=Response.newBuilder().mergeFrom(sm.getBody()).build();
      for(ResponseListener lis:listeners){
        lis.onResponse(resp);
      }
    }else if(sm.getKind()==Kind.WEB_RESPONSE){
      final WebResponse resp=WebResponse.newBuilder().mergeFrom(sm.getBody()).build();
      for(ResponseListener lis:listeners){
        lis.onWebResponse(resp);
      }
    }
    super.messageReceived(ctx, e);
  }
  @Override
  public void channelDisconnected(ChannelHandlerContext ctx,
      ChannelStateEvent e) throws Exception {
    super.channelDisconnected(ctx, e);
    SocketLog.info("worker disconnect to master");
    //断开连接,如果还有运行中的job,将这些job取消掉
    for(String jobId:new HashSet<String>(context.getRunnings().keySet())){
      context.getRunnings().get(jobId).getJobContext().getJobHistory().getLog().appendZeus("worker与master断开连接,worker主动取消该任务");
      context.getClientWorker().cancelScheduleJob(jobId);
    }
    for(String debugId:new HashSet<String>(context.getDebugRunnings().keySet())){
      context.getDebugRunnings().get(debugId).getJobContext().getJobHistory().getLog().appendZeus("worker与master断开连接,worker主动取消该任务");
      context.getClientWorker().cancelDebugJob(debugId);
    }
    for(String historyId:new HashSet<String>(context.getManualRunnings().keySet())){
      context.getManualRunnings().get(historyId).getJobContext().getJobHistory().getLog().appendZeus("worker与master断开连接,worker主动取消该任务");
      context.getClientWorker().cancelManualJob(historyId);
    }
    this.context.setServerChannel(null);
  }
  private List<ResponseListener> listeners=new CopyOnWriteArrayList<ResponseListener>();
  public static interface ResponseListener{
    public void onResponse(Response resp);
    public void onWebResponse(WebResponse resp);
  }
  public void addListener(ResponseListener listener){
    listeners.add(listener);
  }
  public void removeListener(ResponseListener listener){
    listeners.remove(listener);
  }
}
TOP

Related Classes of com.taobao.zeus.socket.worker.WorkerHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.