package com.taobao.zeus.socket.master.reqresp; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import com.taobao.zeus.model.JobHistory; import com.taobao.zeus.socket.SocketLog; import com.taobao.zeus.socket.master.AtomicIncrease; import com.taobao.zeus.socket.master.MasterContext; import com.taobao.zeus.socket.master.MasterWorkerHolder; import com.taobao.zeus.socket.master.MasterHandler.ResponseListener; import com.taobao.zeus.socket.protocol.Protocol.DebugMessage; import com.taobao.zeus.socket.protocol.Protocol.ExecuteKind; import com.taobao.zeus.socket.protocol.Protocol.ExecuteMessage; import com.taobao.zeus.socket.protocol.Protocol.ManualMessage; 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; public class MasterExecuteJob { /** * master向worker发送执行job的指令 * @param context * @param jobId * @return */ public Future<Response> executeJob(final MasterContext context,final MasterWorkerHolder holder,ExecuteKind ek,final String id){ if(ek==ExecuteKind.ManualKind){ return processManual(context, holder, id); }else if(ek==ExecuteKind.ScheduleKind){ return processSchedule(context, holder, id); }else if(ek==ExecuteKind.DebugKind){ return processDebug(context, holder, id); } return null; } private Future<Response> processSchedule(final MasterContext context,final MasterWorkerHolder holder,final String id){ // 向channel 发送执行job命令 // 等待worker响应 // 响应OK 则添加监听器,继续等待任务完成的消息 // 响应失败,返回失败退出码 JobHistory history=context.getJobHistoryManager().findJobHistory(id); final String jobId=history.getJobId(); holder.getRunnings().put(jobId,false); ExecuteMessage em=ExecuteMessage.newBuilder().setJobId(jobId).build(); final Request req=Request.newBuilder().setRid(AtomicIncrease.getAndIncrement()).setOperate(Operate.Schedule) .setBody(em.toByteString()).build(); SocketMessage sm=SocketMessage.newBuilder().setKind(Kind.REQUEST).setBody(req.toByteString()).build(); Future<Response> f=context.getThreadPool().submit(new Callable<Response>() { private Response response; public Response call() throws Exception { final CountDownLatch latch=new CountDownLatch(1); context.getHandler().addListener(new ResponseListener() { public void onWebResponse(WebResponse resp) {} public void onResponse(Response resp) { if(resp.getRid()==req.getRid()){ context.getHandler().removeListener(this); response=resp; latch.countDown(); } } }); try { latch.await(); } finally{ holder.getRunnings().remove(jobId); } return response; } }); holder.getChannel().write(sm); SocketLog.info("master send execute command to worker,rid="+req.getRid()+",jobId="+jobId); return f; } private Future<Response> processManual(final MasterContext context,final MasterWorkerHolder holder,final String historyId){ // 向channel 发送执行job命令 // 等待worker响应 // 响应OK 则添加监听器,继续等待任务完成的消息 // 响应失败,返回失败退出码 holder.getManualRunnings().put(historyId,false); ManualMessage mm=ManualMessage.newBuilder().setHistoryId(historyId).build(); final Request req=Request.newBuilder().setRid(AtomicIncrease.getAndIncrement()).setOperate(Operate.Manual) .setBody(mm.toByteString()).build(); SocketMessage sm=SocketMessage.newBuilder().setKind(Kind.REQUEST).setBody(req.toByteString()).build(); Future<Response> f=context.getThreadPool().submit(new Callable<Response>() { private Response response; public Response call() throws Exception { final CountDownLatch latch=new CountDownLatch(1); context.getHandler().addListener(new ResponseListener() { public void onWebResponse(WebResponse resp) {} public void onResponse(Response resp) { if(resp.getRid()==req.getRid()){ context.getHandler().removeListener(this); response=resp; latch.countDown(); } } }); try { latch.await(); } finally{ holder.getManualRunnings().remove(historyId); } return response; } }); holder.getChannel().write(sm); SocketLog.info("master send manual command to worker,rid="+req.getRid()+",historyId="+historyId); return f; } private Future<Response> processDebug(final MasterContext context,final MasterWorkerHolder holder,final String id){ // 向channel 发送执行job命令 // 等待worker响应 // 响应OK 则添加监听器,继续等待任务完成的消息 // 响应失败,返回失败退出码 holder.getDebugRunnings().put(id,false); DebugMessage dm=DebugMessage.newBuilder().setDebugId(id).build(); final Request req=Request.newBuilder().setRid(AtomicIncrease.getAndIncrement()).setOperate(Operate.Debug) .setBody(dm.toByteString()).build(); SocketMessage sm=SocketMessage.newBuilder().setKind(Kind.REQUEST).setBody(req.toByteString()).build(); Future<Response> f=context.getThreadPool().submit(new Callable<Response>() { private Response response; public Response call() throws Exception { final CountDownLatch latch=new CountDownLatch(1); context.getHandler().addListener(new ResponseListener() { public void onWebResponse(WebResponse resp) {} public void onResponse(Response resp) { if(resp.getRid()==req.getRid()){ context.getHandler().removeListener(this); response=resp; latch.countDown(); } } }); try { latch.await(); } finally{ holder.getDebugRunnings().remove(id); } return response; } }); holder.getChannel().write(sm); SocketLog.info("master send debug command to worker,rid="+req.getRid()+",debugId="+id); return f; } }