大任务异步处理,帮您搞定大数据批量处理体验
1. 背景说明
在实现引入、引出、凭证生成、存货核算等功能时,需要处理成千上万的数据量,非常耗时。如果没有进度显示,用户体验就非常糟糕。
大任务异步处理框架,旨在提供一套统一的解决方案,预封装一批服务接口,可以很方便的实现任务后台异步执行,前端同步显示进度的效果,并统一对任务进行管理,生成执行日志。
业务领域使用这套统一的框架,可以无需关心后台异步线程的启动和管理,直接沿用平台已经封装好的进度显示界面。只需要专注于实现功能逻辑,提升开发效率,保障用户体验。
本文先分场景演示如何调用这些接口,然后介绍大任务异步处理框架对外提供的服务接口。
2. 场景演示
用户点击界面上的按钮,启动任务执行(异步线程执行),并自动弹出一个进度显示界面,定时读取任务执行进度。
任务执行完毕,自动关闭进度界面,并通知父界面进行后续处理。
3. 实现步骤
第一步:派生kd.bos.AbstractTask类(或Task接口),实现任务执行类,重写execute方法。
第二步:编写任务发起界面插件,捕获按钮点击事件,创建一个新任务,调用JobForm的方法,发布任务,显示任务进度界面。
4. 示例代码
第一步:实现Task接口
Java | |
package kd.bos.plugin.sample.schedule;
import java.util.HashMap; import java.util.Map;
import kd.bos.context.RequestContext; import kd.bos.exception.KDBizException; import kd.bos.exception.KDException; import kd.bos.logging.Log; import kd.bos.logging.LogFactory; import kd.bos.schedule.executor.AbstractTask;
/** * 后台任务实现类,测试用 * * @author rd_johnnyding * @remark * * 根据传入的循环执行次数,循环执行,每次循环输出当前进度 */ public class MyTask extends AbstractTask {
private static final Log log = LogFactory.getLog(MyTask.class);
@Override public void execute(RequestContext rc, Map<String, Object> params) throws KDException {
// 任务开始,输出当前进度及提示 feedbackProgress(0, "已经进入任务执行环节,开始执行任务", null);
// 从输入参数中,获取输入的循环次数 (默认20次) int time = 20; if (params.containsKey("time")) { time = (int)params.get("time"); } if (time > 100 || time <= 0) { throw new KDBizException(String.format("设置的次数不合理,合理范围是[1,100]", time)); }
try { int progress = 0; for (int i = 0; i < time; i++) {
// 反馈进度 String desc = String.format("开始进行第 %s / %s 次循环", i+1, time); progress = (100 * i) / time; feedbackProgress(progress, desc, null);
// 判断前端是否下达了终止任务的指令 if (isStop()) { stop(); }
// 执行业务逻辑,此处假设需要耗时500ms,暂停5000ms Thread.sleep(500); } } catch (InterruptedException e) { // 输出monitor日志 log.error(e); }
// 任务执行完毕,生成执行结果输出 HashMap<String, Object> result = new HashMap<>(); result.put("success", "true");
// 输出定制结果 feedbackCustomdata(result); } } |
第二步:发布任务
Java | |
package kd.bos.plugin.sample.schedule;
import java.util.EventObject; import java.util.HashMap; import java.util.Map; import java.util.UUID;
import kd.bos.dataentity.serialization.SerializationUtils; import kd.bos.dataentity.utils.StringUtils; import kd.bos.form.CloseCallBack; import kd.bos.form.control.Control; import kd.bos.form.events.ClosedCallBackEvent; import kd.bos.form.plugin.AbstractFormPlugin; import kd.bos.schedule.api.JobInfo; import kd.bos.schedule.api.JobType; import kd.bos.schedule.api.TaskInfo; import kd.bos.schedule.formplugin.JobForm;
/** * 任务发布界面插件 * * @author rd_johnnyding * * @remark * 演示如何发起一个任务,并显示任务进度界面,捕获任务结束事件 */ public class JobDispatchFormPlugin extends AbstractFormPlugin {
private static final String KEY_JOBDISPATCH = "btnjobdispatch";
/** * 添加事件监听:"启动任务"按钮点击事件 */ @Override public void registerListener(EventObject e) { super.registerListener(e);
this.addClickListeners(KEY_JOBDISPATCH); }
/** * 事件处理:"启动任务"按钮点击事件 */ @Override public void click(EventObject evt) { Control source = (Control)evt.getSource(); if (StringUtils.equalsIgnoreCase(KEY_JOBDISPATCH, source.getKey())) { this.dispatch(); } }
/** * 回调事件,在任务处理完毕后继续后续处理 */ @Override public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) { super.closedCallBack(closedCallBackEvent);
if (StringUtils.equals(closedCallBackEvent.getActionId(), "taskcloseback")) { this.taskCallBack(closedCallBackEvent.getReturnData()); } }
/** * 创建任务目标,发布新任务 */ private void dispatch() {
// 创建任务目标 JobInfo jobInfo = new JobInfo(); jobInfo.setAppId("bos"); // 执行类所在的应用名 jobInfo.setJobType(JobType.REALTIME); // 即时执行 jobInfo.setName("test job"); jobInfo.setId(UUID.randomUUID().toString()); // 随机产生一个JobId (任务目标的标识) jobInfo.setTaskClassname("kd.bos.plugin.sample.schedule.MyTask");
// 自定义参数 Map<String,Object> params = new HashMap<>(); params.put("time", 80); // 自定义参数,示例任务执行循环次数,80次 jobInfo.setParams(params);
// 回调参数,设置一个回调处理标识(actionId) CloseCallBack closeCallBack = new CloseCallBack(this, "taskcloseback");
// 发布任务,并显示进度 JobForm.dispatch(jobInfo, this.getView(), closeCallBack); }
/** * 任务完成后的回调处理 * * @param returnData */ private void taskCallBack(Object returnData) { if (returnData == null) { return; }
if (returnData instanceof Map<?, ?>) { @SuppressWarnings("unchecked") Map<String, Object> result = (Map<String, Object>)returnData; if (result.containsKey("taskinfo")) { String taskInfoStr = (String)result.get("taskinfo"); if (StringUtils.isNotBlank(taskInfoStr)) { TaskInfo taskInfo = SerializationUtils.fromJsonString(taskInfoStr, TaskInfo.class);
if (taskInfo.isTaskEnd()) { // 获取任务执行完毕,生成的内容 String data = taskInfo.getData(); this.getView().showMessage(data); } } } } } } |
大任务异步处理,帮您搞定大数据批量处理体验
本文2024-09-23 00:23:26发表“云苍穹知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-cangqiong-139158.html