/** * 注册作业完成信息. * * @param jobExecutionShardingContext 作业运行时分片上下文 */ public void registerJobCompleted( final JobExecutionMultipleShardingContext jobExecutionShardingContext) { if (!configService.isMonitorExecution()) { return; } serverService.updateServerStatus(ServerStatus.READY); for (int each : jobExecutionShardingContext.getShardingItems()) { jobNodeStorage.createJobNodeIfNeeded(ExecutionNode.getCompletedNode(each)); jobNodeStorage.removeJobNodeIfExisted(ExecutionNode.getRunningNode(each)); jobNodeStorage.replaceJobNode( ExecutionNode.getLastCompleteTimeNode(each), System.currentTimeMillis()); } }
/** * 设置任务被错过执行的标记. * * @param items 需要设置错过执行的任务分片项 */ public void setMisfire(final List<Integer> items) { if (!configService.isMonitorExecution()) { return; } for (int each : items) { jobNodeStorage.createJobNodeIfNeeded(ExecutionNode.getMisfireNode(each)); } }
/** * 注册作业启动信息. * * @param jobExecutionShardingContext 作业运行时分片上下文 */ public void registerJobBegin( final JobExecutionMultipleShardingContext jobExecutionShardingContext) { if (!jobExecutionShardingContext.getShardingItems().isEmpty() && configService.isMonitorExecution()) { serverService.updateServerStatus(ServerStatus.RUNNING); for (int each : jobExecutionShardingContext.getShardingItems()) { jobNodeStorage.fillEphemeralJobNode(ExecutionNode.getRunningNode(each), ""); jobNodeStorage.replaceJobNode( ExecutionNode.getLastBeginTimeNode(each), System.currentTimeMillis()); Date nextFireTime = JobRegistry.getInstance().getJob(jobConfiguration.getJobName()).getNextFireTime(); if (null != nextFireTime) { jobNodeStorage.replaceJobNode( ExecutionNode.getNextFireTimeNode(each), nextFireTime.getTime()); } } } }
/** * 获取标记被错过执行的任务分片项. * * @param items 需要获取标记被错过执行的任务分片项 * @return 标记被错过执行的任务分片项 */ public List<Integer> getMisfiredJobItems(final List<Integer> items) { List<Integer> result = new ArrayList<>(items.size()); for (int each : items) { if (jobNodeStorage.isJobNodeExisted(ExecutionNode.getMisfireNode(each))) { result.add(each); } } return result; }
public IProcess execute(final Command command, IPipe in, IPipe out) throws CoreException { ExecutionNode node = new ExecutionNode(); node.command = (Command) EcoreUtil.copy(command); node.input = in == null ? createPipe().close(Status.OK_STATUS) : in; node.output = out == null ? createPipe() : out; node.process = new Process(this, node.input, node.output); try { commands.put(node); } catch (InterruptedException e) { throw new CoreException( new Status( Status.ERROR, EclTcpClientPlugin.PLUGIN_ID, "Failed to execute ecl command: " + command.getClass().getName(), e)); } return node.process; }
/** * 判断分片项中是否还有执行中的作业. * * @param items 需要判断的分片项列表 * @return 分片项中是否还有执行中的作业 */ public boolean hasRunningItems(final List<Integer> items) { if (!configService.isMonitorExecution()) { return false; } for (int each : items) { if (jobNodeStorage.isJobNodeExisted(ExecutionNode.getRunningNode(each))) { return true; } } return false; }
/** 清理作业上次运行时信息. 只会在主节点进行. */ public void cleanPreviousExecutionInfo() { if (!isExecutionNodeExisted()) { return; } if (leaderElectionService.isLeader()) { jobNodeStorage.fillEphemeralJobNode(ExecutionNode.CLEANING, ""); List<Integer> items = getAllItems(); for (int each : items) { jobNodeStorage.removeJobNodeIfExisted(ExecutionNode.getCompletedNode(each)); } if (jobNodeStorage.isJobNodeExisted(ExecutionNode.NECESSARY)) { fixExecutionInfo(items); } jobNodeStorage.removeJobNodeIfExisted(ExecutionNode.CLEANING); } while (jobNodeStorage.isJobNodeExisted(ExecutionNode.CLEANING)) { BlockUtils.waitingShortTime(); } }
@Test public void assertGetMisfireNode() { assertThat(ExecutionNode.getMisfireNode(0), is("execution/0/misfire")); }
@Test public void assertGetLastCompleteTimeNode() { assertThat(ExecutionNode.getLastCompleteTimeNode(0), is("execution/0/lastCompleteTime")); }
@Test public void assertGetNextFireTimeNode() { assertThat(ExecutionNode.getNextFireTimeNode(0), is("execution/0/nextFireTime")); }
@Test public void assertGetCompletedNode() { assertThat(ExecutionNode.getCompletedNode(0), is("execution/0/completed")); }
@Test public void assertGetRunningNode() { assertThat(ExecutionNode.getRunningNode(0), is("execution/0/running")); }
/** * 清除分配分片序列号的运行状态. * * <p>用于作业服务器恢复连接注册中心而重新上线的场景, 先清理上次运行时信息. * * @param items 需要清理的分片项列表 */ public void clearRunningInfo(final List<Integer> items) { for (int each : items) { jobNodeStorage.removeJobNodeIfExisted(ExecutionNode.getRunningNode(each)); } }
/** * 判断该分片是否已完成. * * @param item 运行中的分片路径 * @return 该分片是否已完成 */ public boolean isCompleted(final int item) { return jobNodeStorage.isJobNodeExisted(ExecutionNode.getCompletedNode(item)); }
/** * 清除任务被错过执行的标记. * * @param items 需要清除错过执行的任务分片项 */ public void clearMisfire(final List<Integer> items) { for (int each : items) { jobNodeStorage.removeJobNodeIfExisted(ExecutionNode.getMisfireNode(each)); } }
@Test public void assertGetItemWhenNotRunningItemPath() { assertNull(executionNode.getItemByRunningItemPath("/test_job/execution/0/completed")); }
@Test public void assertGetItemByRunningItemPath() { assertThat(executionNode.getItemByRunningItemPath("/test_job/execution/0/running"), is(0)); }
private boolean isRunningItem(final int item) { return jobNodeStorage.isJobNodeExisted(ExecutionNode.getRunningNode(item)); }