spring-boot - 从 Spring Batch Tasklet 获取进度信息
问题描述
我正在尝试为当前正在运行的 spring 批处理 tasklet 设置和检索进度信息。
我有一个基于一步的简单春季批处理作业,例如。
public Step jobStep() {
return stepBuilderFactory.get(JOB_STEP_1)
.tasklet((contribution, chunkContext) -> {
...
}).build();
}
tasklet 是一个简单的循环做一些事情,这可能需要很多时间。
在循环中的每次迭代之后,我都会在 JobExecutionContext 中设置一些进度信息,例如。
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("myJobStatus", "10 of 100 finished");
从另一个线程(例如休息服务)我想检查实际小任务的进度,我为此使用 JobExplorer
String status = (String)jobExplorer.getJobExecution(jobId).getExecutionContext().get("myJobStatus");
不幸的是,myJobStatus 属性仅在步骤或作业完成时设置。我什至尝试用步骤循环替换简单循环,但结果相同。
是否有另一种方法可以设置和访问当前正在运行的作业的进度信息?
我将 DefaultBatchConfigurer 与基于 JDBC 的 JobRepository 等一起使用。
解决方案
您的问题是您将进度信息保存在作业执行上下文中,该信息在步骤完成后保存在作业存储库中。您需要改用 step 执行上下文,因为它在 tasklet 的每次提交时保存。以下是参考文档中执行上下文部分的摘录:
它们是两个不同的 ExecutionContext。范围为 Step 的内容保存在 Step 中的每个提交点,而范围为 Job 的内容保存在每次 Step 执行之间。
因此,如果您将进度信息存储在步骤执行上下文(而不是作业执行上下文)中,您应该能够使用作业资源管理器从其他线程获取它。我假设您的 tasklet 做了一些工作,将进度保存在步骤执行上下文中,然后 return CONTINUABLE
,直到没有更多工作要做并FINISHED
在此时返回。我在这个 repo中有一个完整的例子,但这里是相关部分:
class MyTasklet implements Tasklet {
private int progress;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
RepeatStatus repeatStatus;
if (moreWork()) {
doSomeWork();
repeatStatus = RepeatStatus.CONTINUABLE;
} else {
repeatStatus = RepeatStatus.FINISHED;
}
reportProgress(chunkContext);
return repeatStatus;
}
private void reportProgress(ChunkContext chunkContext) {
chunkContext.getStepContext().getStepExecution()
.getExecutionContext().putInt("progress", this.progress++);
}
private void doSomeWork() throws Exception {
Thread.sleep(5000);
System.out.println("doing some work..");
}
private boolean moreWork() {
return this.progress < 100;
}
}
推荐阅读
- reactjs - 带有 Reactjs 的 DHTMLX 甘特图不显示滚动
- python - Tensorflow 2:如何在自定义损失中使用张量 y_true 的形状?
- intellij-idea - IntelliJ/WebStorm 的过时 CloudFormation 模式?
- java - What re the restrictions around Java EXPLICIT type conversion?
- typescript - 当它们具有相同的名称时,如何强制打字稿将参数解释为命名空间而不是类 - gRPC
- youtube-dl - gTEHbBBl_dY:YouTube 说:无法提取视频数据
- ios - 自定义 UIView 子类中的 Swift UIView 子视图不圆角
- azure - 如何获取登录我的 Web 应用程序的用户的帐户 ID(订阅 ID)和租户 ID?
- react-native - Error when building apk with gradlew assembleRelease
- javascript - 计算开始时间为 09:00 AM 的日历天 Rails