From 0cc24f50a28c7e550b6b237a647ee60e60afba5d Mon Sep 17 00:00:00 2001 From: chenzhihang <709011834@qq.com> Date: Fri, 25 Apr 2025 10:06:20 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9C=BA=E5=99=A8=E5=AD=A6?= =?UTF-8?q?=E4=B9=A0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/autoML/AutoMlController.java | 1 + .../machineLearn/MachineLearnController.java | 61 +++++ .../MachineLearnInsController.java | 60 ++++ .../ruoyi/platform/domain/MachineLearn.java | 42 +++ .../platform/domain/MachineLearnIns.java | 51 ++++ .../platform/mapper/MachineLearnDao.java | 23 ++ .../platform/mapper/MachineLearnInsDao.java | 23 ++ .../platform/scheduling/MLStatusTask.java | 119 ++++++++ .../service/MachineLearnInsService.java | 28 ++ .../platform/service/MachineLearnService.java | 19 ++ .../impl/MachineLearnInsServiceImpl.java | 259 ++++++++++++++++++ .../service/impl/MachineLearnServiceImpl.java | 220 +++++++++++++++ .../service/impl/NewDatasetServiceImpl.java | 36 +-- .../TextClassificationInsServiceImpl.java | 2 +- .../vo/TextClassificationParamVo.java | 2 + .../MachineLearnDaoMapper.xml | 82 ++++++ .../MachineLearnInsDaoMapper.xml | 83 ++++++ 17 files changed, 1089 insertions(+), 22 deletions(-) create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnController.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnInsController.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearn.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearnIns.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnDao.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnInsDao.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/MLStatusTask.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnInsService.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnService.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnInsServiceImpl.java create mode 100644 ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnServiceImpl.java create mode 100644 ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnDaoMapper.xml create mode 100644 ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnInsDaoMapper.xml diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/autoML/AutoMlController.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/autoML/AutoMlController.java index 9c1028bb..64c419c6 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/autoML/AutoMlController.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/autoML/AutoMlController.java @@ -44,6 +44,7 @@ public class AutoMlController extends BaseController { public GenericsAjaxResult editAutoMl(@RequestBody AutoMlVo autoMlVo) throws Exception { return genericsSuccess(this.autoMlService.edit(autoMlVo)); } + @GetMapping("/getAutoMlDetail") @ApiOperation("获取自动机器学习详细信息") public GenericsAjaxResult getAutoMlDetail(@RequestParam("id") Long id) throws IOException { diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnController.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnController.java new file mode 100644 index 00000000..5d08e5dd --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnController.java @@ -0,0 +1,61 @@ +package com.ruoyi.platform.controller.machineLearn; + +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.GenericsAjaxResult; +import com.ruoyi.platform.domain.MachineLearn; +import com.ruoyi.platform.service.MachineLearnService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RestController +@RequestMapping("machineLearn") +@Api("自动机器学习") +public class MachineLearnController extends BaseController { + @Resource + private MachineLearnService machineLearnService; + + @GetMapping + @ApiOperation("分页查询") + public GenericsAjaxResult> queryByPage(@RequestParam("page") int page, + @RequestParam("size") int size, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "type", required = false) String type) { + PageRequest pageRequest = PageRequest.of(page, size); + return genericsSuccess(this.machineLearnService.queryByPage(name, type, pageRequest)); + } + + @PostMapping + @ApiOperation("新增自动机器学习") + public GenericsAjaxResult add(@RequestBody MachineLearn machineLearn) { + return genericsSuccess(this.machineLearnService.add(machineLearn)); + } + + @PutMapping + @ApiOperation("编辑自动机器学习") + public GenericsAjaxResult edit(@RequestBody MachineLearn machineLearn) throws Exception { + return genericsSuccess(this.machineLearnService.edit(machineLearn)); + } + + @GetMapping("/getMLDetail") + @ApiOperation("获取自动机器学习详细信息") + public GenericsAjaxResult getMLDetail(@RequestParam("id") Long id) { + return genericsSuccess(this.machineLearnService.getMLDetail(id)); + } + + @DeleteMapping("{id}") + @ApiOperation("删除自动机器学习") + public GenericsAjaxResult delete(@PathVariable("id") Long id) { + return genericsSuccess(this.machineLearnService.delete(id)); + } + + @PostMapping("/run/{id}") + @ApiOperation("运行自动机器学习") + public GenericsAjaxResult runMachineLearn(@PathVariable("id") Long id) throws Exception { + return genericsSuccess(this.machineLearnService.runMachineLearn(id)); + } +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnInsController.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnInsController.java new file mode 100644 index 00000000..c4e83c97 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/machineLearn/MachineLearnInsController.java @@ -0,0 +1,60 @@ +package com.ruoyi.platform.controller.machineLearn; + +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.GenericsAjaxResult; +import com.ruoyi.platform.domain.MachineLearnIns; +import com.ruoyi.platform.service.MachineLearnInsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import javax.annotation.Resource; +import java.util.List; + +@RestController +@RequestMapping("machineLearnIns") +@Api("自动机器学习实验实例") +public class MachineLearnInsController extends BaseController { + + @Resource + private MachineLearnInsService machineLearnInsService; + + @GetMapping + @ApiOperation("分页查询") + public GenericsAjaxResult> queryByPage(Long machineLearnId, int page, int size) { + PageRequest pageRequest = PageRequest.of(page, size); + return genericsSuccess(this.machineLearnInsService.queryByPage(machineLearnId, pageRequest)); + } + + @PostMapping + @ApiOperation("新增实验实例") + public GenericsAjaxResult add(@RequestBody MachineLearnIns machineLearnIns) { + return genericsSuccess(this.machineLearnInsService.insert(machineLearnIns)); + } + + @DeleteMapping("{id}") + @ApiOperation("删除实验实例") + public GenericsAjaxResult deleteById(@PathVariable("id") Long id) { + return genericsSuccess(this.machineLearnInsService.removeById(id)); + } + + @DeleteMapping("batchDelete") + @ApiOperation("批量删除实验实例") + public GenericsAjaxResult batchDelete(@RequestBody List ids) { + return genericsSuccess(this.machineLearnInsService.batchDelete(ids)); + } + + @PutMapping("{id}") + @ApiOperation("终止实验实例") + public GenericsAjaxResult terminateMLIns(@PathVariable("id") Long id) throws Exception { + return genericsSuccess(this.machineLearnInsService.terminateMLIns(id)); + } + + @GetMapping("{id}") + @ApiOperation("查看实验实例详情") + public GenericsAjaxResult getDetailById(@PathVariable("id") Long id) { + return genericsSuccess(this.machineLearnInsService.getDetailById(id)); + } +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearn.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearn.java new file mode 100644 index 00000000..110c6476 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearn.java @@ -0,0 +1,42 @@ +package com.ruoyi.platform.domain; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +@ApiModel(description = "机器学习") +public class MachineLearn { + private Long id; + + private Long experimentId; + + @ApiModelProperty(value = "类型") + private String type; + + @ApiModelProperty(value = "实验名称") + private String name; + + @ApiModelProperty(value = "实验描述") + private String description; + + private String param; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + + private Integer state; + + @ApiModelProperty(value = "状态列表") + private String statusList; +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearnIns.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearnIns.java new file mode 100644 index 00000000..120cf68d --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/MachineLearnIns.java @@ -0,0 +1,51 @@ +package com.ruoyi.platform.domain; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +@ApiModel(description = "自动机器学习实验实例") +public class MachineLearnIns { + + private Long id; + + private Long machineLearnId; + + private String type; + + private String resultPath; + + private String modelPath; + + private String imgPath; + + private String runHistoryPath; + + private Integer state; + + private String status; + + private String nodeStatus; + + private String nodeResult; + + private String param; + + @ApiModelProperty(value = "Argo实例名称") + private String argoInsName; + + @ApiModelProperty(value = "Argo命名空间") + private String argoInsNs; + + private Date createTime; + + private Date updateTime; + + private Date finishTime; +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnDao.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnDao.java new file mode 100644 index 00000000..7b954e2f --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnDao.java @@ -0,0 +1,23 @@ +package com.ruoyi.platform.mapper; + +import com.ruoyi.platform.domain.MachineLearn; +import org.apache.ibatis.annotations.Param; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface MachineLearnDao { + long count(@Param("name") String name, @Param("type") String type); + + List queryByPage(@Param("name") String name, @Param("type") String type, @Param("pageable") Pageable pageable); + + int save(@Param("machineLearn") MachineLearn machineLearn); + + int edit(@Param("machineLearn") MachineLearn machineLearn); + + MachineLearn getMachineLearnById(@Param("id") Long id); + + MachineLearn getMachineLearnByName(@Param("name") String name); + + List queryByDatasetId(@Param("datasetId") String datasetId); +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnInsDao.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnInsDao.java new file mode 100644 index 00000000..2267a830 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/MachineLearnInsDao.java @@ -0,0 +1,23 @@ +package com.ruoyi.platform.mapper; + +import com.ruoyi.platform.domain.MachineLearnIns; +import org.apache.ibatis.annotations.Param; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface MachineLearnInsDao { + long count(@Param("machineLearnId") Long machineLearnId); + + List queryAllByLimit(@Param("machineLearnId") Long machineLearnId, @Param("pageable") Pageable pageable); + + List getByMachineLearnId(@Param("machineLearnId") Long machineLearnId); + + int insert(@Param("machineLearnIns") MachineLearnIns machineLearnIns); + + int update(@Param("machineLearnIns") MachineLearnIns machineLearnIns); + + MachineLearnIns queryById(@Param("id") Long id); + + List queryNotTerminated(); +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/MLStatusTask.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/MLStatusTask.java new file mode 100644 index 00000000..473c0079 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/MLStatusTask.java @@ -0,0 +1,119 @@ +package com.ruoyi.platform.scheduling; + +import com.ruoyi.platform.domain.*; +import com.ruoyi.platform.mapper.MachineLearnDao; +import com.ruoyi.platform.mapper.MachineLearnInsDao; +import com.ruoyi.platform.mapper.ResourceOccupyDao; +import com.ruoyi.platform.service.MachineLearnInsService; +import com.ruoyi.platform.service.ResourceOccupyService; +import com.ruoyi.system.api.constant.Constant; +import org.apache.commons.lang3.StringUtils; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +@Component() +public class MLStatusTask { + @Resource + private MachineLearnInsService machineLearnInsService; + @Resource + private MachineLearnInsDao machineLearnInsDao; + @Resource + private MachineLearnDao machineLearnDao; + @Resource + private ResourceOccupyDao resourceOccupyDao; + @Resource + private ResourceOccupyService resourceOccupyService; + + private List machineLearnIds = new ArrayList<>(); + + @Scheduled(cron = "0/30 * * * * ?") // 每30S执行一次 + public void executeMachineLearnInsStatus() { + // 首先查到所有非终止态的实验实例 + List insList = machineLearnInsService.queryNotTerminated(); + + // 去argo查询状态 + List updateList = new ArrayList<>(); + if (insList != null && insList.size() > 0) { + for (MachineLearnIns ins : insList) { + //当原本状态为null或非终止态时才调用argo接口 + try { + Long userId = resourceOccupyDao.getResourceOccupyByTask(Constant.TaskType_ML, ins.getMachineLearnId(), ins.getId(), null).get(0).getUserId(); + if (userId != null) { + if (resourceOccupyDao.getUserCredit(userId) <= 0) { + ins.setStatus(Constant.Failed); + machineLearnInsService.terminateMLIns(ins.getId()); + } else { + ins = machineLearnInsService.queryStatusFromArgo(ins); + // 扣除积分 + if (Constant.Running.equals(ins.getStatus())) { + resourceOccupyService.deducing(Constant.TaskType_ML, null, ins.getId(), null, null); + } else if (Constant.Failed.equals(ins.getStatus()) || Constant.Terminated.equals(ins.getStatus()) + || Constant.Succeeded.equals(ins.getStatus())) { + resourceOccupyService.endDeduce(Constant.TaskType_ML, null, ins.getId(), null, null); + } + } + } else { + ins = machineLearnInsService.queryStatusFromArgo(ins); + } + } catch (Exception e) { + ins.setStatus(Constant.Failed); + // 结束扣除积分 + resourceOccupyService.endDeduce(Constant.TaskType_ML, null, ins.getId(), null, null); + } + // 线程安全的添加操作 + synchronized (machineLearnIds) { + machineLearnIds.add(ins.getMachineLearnId()); + } + updateList.add(ins); + if (updateList.size() > 0) { + for (MachineLearnIns machineLearnIns : updateList) { + machineLearnInsDao.update(machineLearnIns); + } + } + } + } + } + + @Scheduled(cron = "0/30 * * * * ?") // / 每30S执行一次 + public void executeMachineLearn() { + if (machineLearnIds.size() == 0) { + return; + } + // 存储需要更新的实验对象列表 + List updateMLs = new ArrayList<>(); + for (Long machineLearnId : machineLearnIds) { + // 获取当前实验的所有实例列表 + List insList = machineLearnInsDao.getByMachineLearnId(machineLearnId); + List statusList = new ArrayList<>(); + // 更新实验状态列表 + for (int i = 0; i < insList.size(); i++) { + statusList.add(insList.get(i).getStatus()); + } + String subStatus = statusList.toString().substring(1, statusList.toString().length() - 1); + MachineLearn machineLearn = machineLearnDao.getMachineLearnById(machineLearnId); + if (!StringUtils.equals(machineLearn.getStatusList(), subStatus)) { + machineLearn.setStatusList(subStatus); + updateMLs.add(machineLearn); + machineLearnDao.edit(machineLearn); + } + } + + if (!updateMLs.isEmpty()) { + // 使用Iterator进行安全的删除操作 + Iterator iterator = machineLearnIds.iterator(); + while (iterator.hasNext()) { + Long machineLearnId = iterator.next(); + for (MachineLearn machineLearn : updateMLs) { + if (machineLearn.getId().equals(machineLearnId)) { + iterator.remove(); + } + } + } + } + } +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnInsService.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnInsService.java new file mode 100644 index 00000000..66becd1f --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnInsService.java @@ -0,0 +1,28 @@ +package com.ruoyi.platform.service; + +import com.ruoyi.platform.domain.MachineLearnIns; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import java.util.List; + +public interface MachineLearnInsService { + + Page queryByPage(Long machineLearnId, PageRequest pageRequest); + + MachineLearnIns insert(MachineLearnIns machineLearnIns); + + String removeById(Long id); + + String batchDelete(List ids); + + List queryNotTerminated(); + + MachineLearnIns queryStatusFromArgo(MachineLearnIns machineLearnIns); + + boolean terminateMLIns(Long id) throws Exception; + + MachineLearnIns getDetailById(Long id); + + void updateMLStatus(Long machineLearnId); +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnService.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnService.java new file mode 100644 index 00000000..35c5985a --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/MachineLearnService.java @@ -0,0 +1,19 @@ +package com.ruoyi.platform.service; + +import com.ruoyi.platform.domain.MachineLearn; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +public interface MachineLearnService { + Page queryByPage(String name, String type, PageRequest pageRequest); + + MachineLearn add(MachineLearn machineLearn); + + String edit(MachineLearn machineLearn); + + MachineLearn getMLDetail(Long id); + + String delete(Long id); + + String runMachineLearn(Long id) throws Exception; +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnInsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnInsServiceImpl.java new file mode 100644 index 00000000..2e353807 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnInsServiceImpl.java @@ -0,0 +1,259 @@ +package com.ruoyi.platform.service.impl; + +import com.ruoyi.platform.domain.MachineLearn; +import com.ruoyi.platform.domain.MachineLearnIns; +import com.ruoyi.platform.mapper.MachineLearnDao; +import com.ruoyi.platform.mapper.MachineLearnInsDao; +import com.ruoyi.platform.service.MachineLearnInsService; +import com.ruoyi.platform.service.ResourceOccupyService; +import com.ruoyi.platform.utils.DateUtils; +import com.ruoyi.platform.utils.HttpUtils; +import com.ruoyi.platform.utils.JsonUtils; +import com.ruoyi.system.api.constant.Constant; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; + +@Service +public class MachineLearnInsServiceImpl implements MachineLearnInsService { + @Value("${argo.url}") + private String argoUrl; + @Value("${argo.workflowStatus}") + private String argoWorkflowStatus; + @Value("${argo.workflowTermination}") + private String argoWorkflowTermination; + + @Resource + private MachineLearnInsDao machineLearnInsDao; + @Resource + private MachineLearnDao machineLearnDao; + @Resource + private ResourceOccupyService resourceOccupyService; + + @Override + public Page queryByPage(Long machineLearnId, PageRequest pageRequest) { + long count = machineLearnInsDao.count(machineLearnId); + List machineLearnInsList = machineLearnInsDao.queryAllByLimit(machineLearnId, pageRequest); + return new PageImpl<>(machineLearnInsList, pageRequest, count); + } + + @Override + public MachineLearnIns insert(MachineLearnIns machineLearnIns) { + machineLearnInsDao.insert(machineLearnIns); + return machineLearnIns; + } + + @Override + @Transactional + public String removeById(Long id) { + MachineLearnIns machineLearnIns = machineLearnInsDao.queryById(id); + if (machineLearnIns == null) { + return "实验实例不存在"; + } + if (StringUtils.isEmpty(machineLearnIns.getStatus())) { + machineLearnIns = queryStatusFromArgo(machineLearnIns); + } + if (StringUtils.equals(machineLearnIns.getStatus(), Constant.Running)) { + return "实验实例正在运行,不可删除"; + } + machineLearnIns.setState(Constant.State_invalid); + int update = machineLearnInsDao.update(machineLearnIns); + if (update > 0) { + resourceOccupyService.deleteTaskState(Constant.TaskType_ML, machineLearnIns.getMachineLearnId(), id); + updateMLStatus(machineLearnIns.getMachineLearnId()); + return "删除成功"; + } else { + return "删除失败"; + } + } + + @Override + public String batchDelete(List ids) { + for (Long id : ids) { + String result = removeById(id); + if (!"删除成功".equals(result)) { + return result; + } + } + return "删除成功"; + } + + @Override + public List queryNotTerminated() { + return machineLearnInsDao.queryNotTerminated(); + } + + @Override + public MachineLearnIns queryStatusFromArgo(MachineLearnIns ins) { + String namespace = ins.getArgoInsNs(); + String name = ins.getArgoInsName(); + + // 创建请求数据map + Map requestData = new HashMap<>(); + requestData.put("namespace", namespace); + requestData.put("name", name); + + // 创建发送数据map,将请求数据作为"data"键的值 + Map res = new HashMap<>(); + res.put("data", requestData); + + try { + // 发送POST请求到Argo工作流状态查询接口,并将请求数据转换为JSON + String req = HttpUtils.sendPost(argoUrl + argoWorkflowStatus, null, JsonUtils.mapToJson(res)); + // 检查响应是否为空或无内容 + if (req == null || StringUtils.isEmpty(req)) { + throw new RuntimeException("工作流状态响应为空"); + } + // 将响应的JSON字符串转换为Map对象 + Map runResMap = JsonUtils.jsonToMap(req); + // 从响应Map中获取"data"部分 + Map data = (Map) runResMap.get("data"); + if (data == null || data.isEmpty()) { + throw new RuntimeException("工作流数据为空"); + } + // 从"data"中获取"status"部分,并返回"phase"的值 + Map status = (Map) data.get("status"); + if (status == null || status.isEmpty()) { + throw new RuntimeException("工作流状态为空"); + } + //解析流水线结束时间 + String finishedAtString = (String) status.get("finishedAt"); + if (finishedAtString != null && !finishedAtString.isEmpty()) { + Date finishTime = DateUtils.convertUTCtoShanghaiDate(finishedAtString); + ins.setFinishTime(finishTime); + } + // 解析nodes字段,提取节点状态并转换为JSON字符串 + Map nodes = (Map) status.get("nodes"); + Map modifiedNodes = new LinkedHashMap<>(); + if (nodes != null) { + for (Map.Entry nodeEntry : nodes.entrySet()) { + Map nodeDetails = (Map) nodeEntry.getValue(); + String templateName = (String) nodeDetails.get("displayName"); + modifiedNodes.put(templateName, nodeDetails); + } + } + + String nodeStatusJson = JsonUtils.mapToJson(modifiedNodes); + ins.setNodeStatus(nodeStatusJson); + + //终止态为终止不改 + if (!StringUtils.equals(ins.getStatus(), Constant.Terminated)) { + ins.setStatus(StringUtils.isNotEmpty((String) status.get("phase")) ? (String) status.get("phase") : Constant.Pending); + } + if (StringUtils.equals(ins.getStatus(), Constant.Error)) { + ins.setStatus(Constant.Failed); + } + return ins; + } catch (Exception e) { + throw new RuntimeException("查询状态失败: " + e.getMessage(), e); + } + } + + + @Override + public boolean terminateMLIns(Long id) throws Exception { + MachineLearnIns machineLearnIns = machineLearnInsDao.queryById(id); + if (machineLearnIns == null) { + throw new IllegalStateException("实验实例未查询到"); + } + String currentStatus = machineLearnIns.getStatus(); + String name = machineLearnIns.getArgoInsName(); + String namespace = machineLearnIns.getArgoInsNs(); + + // 获取当前状态,如果为空,则从Argo查询 + if (StringUtils.isEmpty(currentStatus)) { + currentStatus = queryStatusFromArgo(machineLearnIns).getStatus(); + } + // 只有状态是"Running"时才能终止实例 + if (!currentStatus.equalsIgnoreCase(Constant.Running)) { + throw new Exception("终止错误,只有运行状态的实例才能终止"); // 如果不是"Running"状态,则不执行终止操作 + } + + // 创建请求数据map + Map requestData = new HashMap<>(); + requestData.put("namespace", namespace); + requestData.put("name", name); + // 创建发送数据map,将请求数据作为"data"键的值 + Map res = new HashMap<>(); + res.put("data", requestData); + + try { + // 发送POST请求到Argo工作流状态查询接口,并将请求数据转换为JSON + String req = HttpUtils.sendPost(argoUrl + argoWorkflowTermination, null, JsonUtils.mapToJson(res)); + // 检查响应是否为空或无内容 + if (StringUtils.isEmpty(req)) { + throw new RuntimeException("终止响应内容为空"); + + } + // 将响应的JSON字符串转换为Map对象 + Map runResMap = JsonUtils.jsonToMap(req); + // 从响应Map中直接获取"errCode"的值 + Integer errCode = (Integer) runResMap.get("errCode"); + if (errCode != null && errCode == 0) { + MachineLearnIns ins = queryStatusFromArgo(machineLearnIns); + String nodeStatus = ins.getNodeStatus(); + Map nodeMap = JsonUtils.jsonToMap(nodeStatus); + + // 遍历 map + for (Map.Entry entry : nodeMap.entrySet()) { + // 获取每个 Map 中的值并强制转换为 Map + Map innerMap = (Map) entry.getValue(); + // 检查 phase 的值 + if (innerMap.containsKey("phase")) { + String phaseValue = (String) innerMap.get("phase"); + // 如果值不等于 Succeeded,则赋值为 Failed + if (!StringUtils.equals(Constant.Succeeded, phaseValue)) { + innerMap.put("phase", Constant.Failed); + } + } + } + ins.setNodeStatus(JsonUtils.mapToJson(nodeMap)); + ins.setStatus(Constant.Terminated); + ins.setUpdateTime(new Date()); + ins.setFinishTime(new Date()); + machineLearnInsDao.update(ins); + updateMLStatus(ins.getMachineLearnId()); + // 结束扣积分 + resourceOccupyService.endDeduce(Constant.TaskType_ML, null, id, null, null); + return true; + } else { + return false; + } + } catch (Exception e) { + throw new RuntimeException("终止实例错误: " + e.getMessage(), e); + } + } + + @Override + public MachineLearnIns getDetailById(Long id) { + MachineLearnIns machineLearnIns = machineLearnInsDao.queryById(id); + if (Constant.Running.equals(machineLearnIns.getStatus()) || Constant.Pending.equals(machineLearnIns.getStatus())) { + machineLearnIns = queryStatusFromArgo(machineLearnIns); + } + return machineLearnIns; + } + + @Override + public void updateMLStatus(Long machineLearnId) { + List insList = machineLearnInsDao.getByMachineLearnId(machineLearnId); + List statusList = new ArrayList<>(); + // 更新实验状态列表 + for (int i = 0; i < insList.size(); i++) { + statusList.add(insList.get(i).getStatus()); + } + String subStatus = statusList.toString().substring(1, statusList.toString().length() - 1); + MachineLearn machineLearn = machineLearnDao.getMachineLearnById(machineLearnId); + + if (!StringUtils.equals(machineLearn.getStatusList(), subStatus)) { + machineLearn.setStatusList(subStatus); + machineLearnDao.edit(machineLearn); + } + } +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnServiceImpl.java new file mode 100644 index 00000000..bdd9f422 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/MachineLearnServiceImpl.java @@ -0,0 +1,220 @@ +package com.ruoyi.platform.service.impl; + +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.platform.domain.MachineLearn; +import com.ruoyi.platform.domain.MachineLearnIns; +import com.ruoyi.platform.mapper.MachineLearnDao; +import com.ruoyi.platform.mapper.MachineLearnInsDao; +import com.ruoyi.platform.service.MachineLearnInsService; +import com.ruoyi.platform.service.MachineLearnService; +import com.ruoyi.platform.service.ResourceOccupyService; +import com.ruoyi.platform.utils.HttpUtils; +import com.ruoyi.platform.utils.JsonUtils; +import com.ruoyi.platform.vo.AutoMlParamVo; +import com.ruoyi.platform.vo.TextClassificationParamVo; +import com.ruoyi.system.api.constant.Constant; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class MachineLearnServiceImpl implements MachineLearnService { + @Value("${argo.url}") + private String argoUrl; + @Value("${argo.convertAutoML}") + String convertAutoML; + @Value("${argo.convertTextClassification}") + String convertTextClassification; + @Value("${argo.workflowRun}") + private String argoWorkflowRun; + @Value("${minio.endpointIp}") + private String minioEndpoint; + + @Resource + private MachineLearnDao machineLearnDao; + @Resource + private MachineLearnInsDao machineLearnInsDao; + @Resource + private ResourceOccupyService resourceOccupyService; + @Autowired + private MachineLearnInsService machineLearnInsService; + + @Override + public Page queryByPage(String name, String type, PageRequest pageRequest) { + long total = machineLearnDao.count(name, type); + List autoMls = machineLearnDao.queryByPage(name, type, pageRequest); + return new PageImpl<>(autoMls, pageRequest, total); + } + + @Override + public MachineLearn add(MachineLearn machineLearn) { + if (machineLearn.getName().length() >= 64) { + throw new RuntimeException("实验名称大于最大长度"); + } + MachineLearn machineLearnByName = machineLearnDao.getMachineLearnByName(machineLearn.getName()); + if (machineLearnByName != null) { + throw new RuntimeException("实验名称已存在"); + } + String username = SecurityUtils.getLoginUser().getUsername(); + machineLearn.setCreateBy(username); + machineLearn.setUpdateBy(username); + machineLearnDao.save(machineLearn); + return machineLearn; + } + + @Override + public String edit(MachineLearn machineLearn) { + MachineLearn machineLearnByName = machineLearnDao.getMachineLearnByName(machineLearn.getName()); + if (machineLearnByName != null && !machineLearnByName.getId().equals(machineLearn.getId())) { + throw new RuntimeException("实验名称已存在"); + } + machineLearn.setUpdateBy(SecurityUtils.getLoginUser().getUsername()); + machineLearnDao.edit(machineLearn); + return "修改成功"; + } + + @Override + public MachineLearn getMLDetail(Long id) { + return machineLearnDao.getMachineLearnById(id); + } + + @Override + @Transactional + public String delete(Long id) { + MachineLearn machineLearn = machineLearnDao.getMachineLearnById(id); + if (machineLearn == null) { + throw new RuntimeException("实验不存在"); + } + String username = SecurityUtils.getLoginUser().getUsername(); + String createBy = machineLearn.getCreateBy(); + if (!(StringUtils.equals(username, "admin") || StringUtils.equals(username, createBy))) { + throw new RuntimeException("无权限删除该实验"); + } + machineLearn.setUpdateBy(SecurityUtils.getLoginUser().getUsername()); + machineLearn.setState(Constant.State_invalid); + resourceOccupyService.deleteTaskState(Constant.TaskType_ML, id, null); + return machineLearnDao.edit(machineLearn) > 0 ? "删除成功" : "删除失败"; + } + + @Override + @Transactional + public String runMachineLearn(Long id) throws Exception { + MachineLearn machineLearn = machineLearnDao.getMachineLearnById(id); + if (machineLearn == null) { + throw new Exception("自动机器学习配置不存在"); + } + // 调argo转换接口 + try { + String convertRes = null; + String param = null; + String modelType = null; + String taskType = null; + Integer seed = null; + Integer computingResourceId = null; + switch (machineLearn.getType()) { + case Constant.ML_CSV: { + AutoMlParamVo paramVo = JsonUtils.jsonToObject(machineLearn.getParam(), AutoMlParamVo.class); + taskType = paramVo.getTaskType(); + seed = paramVo.getSeed(); + param = JsonUtils.objectToJson(paramVo); + convertRes = HttpUtils.sendPost(argoUrl + convertAutoML, param); + break; + } + case Constant.ML_TextClassification: { + TextClassificationParamVo paramVo = JsonUtils.jsonToObject(machineLearn.getParam(), TextClassificationParamVo.class); + modelType = paramVo.getModelType(); + computingResourceId = paramVo.getComputingResourceId(); + if (resourceOccupyService.haveResource(computingResourceId, 1)) { + param = JsonUtils.getConvertParam(paramVo); + convertRes = HttpUtils.sendPost(argoUrl + convertTextClassification, param); + } + break; + } + case Constant.ML_VideoClassification: { + // todo + break; + } + } + + if (convertRes == null || StringUtils.isEmpty(convertRes)) { + throw new RuntimeException("转换流水线失败"); + } + Map converMap = JsonUtils.jsonToMap(convertRes); + // 组装运行接口json + Map output = (Map) converMap.get("output"); + Map runReqMap = new HashMap<>(); + runReqMap.put("data", converMap.get("data")); + // 调argo运行接口 + String runRes = HttpUtils.sendPost(argoUrl + argoWorkflowRun, JsonUtils.mapToJson(runReqMap)); + + if (runRes == null || StringUtils.isEmpty(runRes)) { + throw new RuntimeException("运行流水线失败"); + } + Map runResMap = JsonUtils.jsonToMap(runRes); + Map data = (Map) runResMap.get("data"); + //判断data为空 + if (data == null || MapUtils.isEmpty(data)) { + throw new RuntimeException("运行流水线失败"); + } + Map metadata = (Map) data.get("metadata"); + // 插入记录到实验实例表 + MachineLearnIns machineLearnIns = new MachineLearnIns(); + machineLearnIns.setMachineLearnId(id); + machineLearnIns.setType(machineLearn.getType()); + machineLearnIns.setArgoInsNs((String) metadata.get("namespace")); + machineLearnIns.setArgoInsName((String) metadata.get("name")); + machineLearnIns.setParam(param); + machineLearnIns.setStatus(Constant.Pending); + //替换argoInsName + String outputString = JsonUtils.mapToJson(output); + machineLearnIns.setNodeResult(outputString.replace("{{workflow.name}}", (String) metadata.get("name"))); + Map param_output = (Map) output.get("param_output"); + List output1 = (ArrayList) param_output.values().toArray()[0]; + Map output2 = (Map) output1.get(0); + String outputPath = minioEndpoint + "/" + output2.get("path").replace("{{workflow.name}}", (String) metadata.get("name")) + "/"; + + switch (machineLearn.getType()) { + case Constant.ML_CSV: { + machineLearnIns.setModelPath(outputPath + "save_model.joblib"); + if (Constant.AutoMl_Classification.equals(taskType)) { + machineLearnIns.setImgPath(outputPath + "Auto-sklearn_metric_over_time.png" + "," + outputPath + "Train_Confusion_Matrix.png" + "," + outputPath + "Test_Confusion_Matrix.png"); + } else { + machineLearnIns.setImgPath(outputPath + "Auto-sklearn_metric_over_time.png" + "," + outputPath + "regression.png"); + } + machineLearnIns.setResultPath(outputPath + "result.txt"); + String seedStr = seed != null ? String.valueOf(seed) : "1"; + machineLearnIns.setRunHistoryPath(outputPath + "smac3-output/run_" + seedStr + "/runhistory.json"); + break; + } + case Constant.ML_TextClassification: { + machineLearnIns.setModelPath(outputPath + "/saved_dict/" + modelType + ".ckpt"); + break; + } + case Constant.ML_VideoClassification: { + break; + } + } + machineLearnInsDao.insert(machineLearnIns); + machineLearnInsService.updateMLStatus(id); + if (computingResourceId != null) { + // 记录开始扣除积分 + resourceOccupyService.startDeduce(computingResourceId, 1, Constant.TaskType_ML, id, machineLearnIns.getId(), null, machineLearn.getName(), null, null); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return "执行成功"; + } +} diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java index 5432f17b..122fd26b 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/NewDatasetServiceImpl.java @@ -51,9 +51,7 @@ public class NewDatasetServiceImpl implements NewDatasetService { @Resource private AssetWorkflowDao assetWorkflowDao; @Resource - private AutoMlDao autoMlDao; - @Resource - private TextClassificationDao textClassificationDao; + private MachineLearnDao machineLearnDao; @Resource private RayDao rayDao; @Resource @@ -422,16 +420,14 @@ public class NewDatasetServiceImpl implements NewDatasetService { HashMap map = new HashMap<>(); map.put("id", String.valueOf(repoId)); - List autoMlList = autoMlDao.queryByDatasetId(JSON.toJSONString(map)); - if (autoMlList != null && !autoMlList.isEmpty()) { - String autoMls = String.join(",", autoMlList.stream().map(AutoMl::getMlName).collect(Collectors.toSet())); - throw new Exception("该数据集被自动机器学习:" + autoMls + "使用,不能删除,请先删除自动机器学习"); - } - List textClassificationList = textClassificationDao.queryByDatasetId(JSON.toJSONString(map)); - if (textClassificationList != null && !textClassificationList.isEmpty()) { - String textClassifications = String.join(",", textClassificationList.stream().map(TextClassification::getName).collect(Collectors.toSet())); - throw new Exception("该数据集被自动机器学习文本分类:" + textClassifications + "使用,不能删除,请先删除自动机器学习文本分类"); + HashMap mLQueryMap = new HashMap<>(); + mLQueryMap.put("dataset", map); + List machineLearnList = machineLearnDao.queryByDatasetId(JSON.toJSONString(mLQueryMap)); + + if (machineLearnList != null && !machineLearnList.isEmpty()) { + String autoMls = String.join(",", machineLearnList.stream().map(MachineLearn::getName).collect(Collectors.toSet())); + throw new Exception("该数据集被自动机器学习:" + autoMls + "使用,不能删除,请先删除自动机器学习"); } List rayList = rayDao.queryByDatasetId(JSON.toJSONString(map)); @@ -471,16 +467,14 @@ public class NewDatasetServiceImpl implements NewDatasetService { HashMap map = new HashMap<>(); map.put("id", String.valueOf(repoId)); map.put("version", version); - List autoMlList = autoMlDao.queryByDatasetId(JSON.toJSONString(map)); - if (autoMlList != null && !autoMlList.isEmpty()) { - String autoMls = String.join(",", autoMlList.stream().map(AutoMl::getMlName).collect(Collectors.toSet())); - throw new Exception("该数据集版本被自动机器学习:" + autoMls + "使用,不能删除,请先删除自动机器学习"); - } - List textClassificationList = textClassificationDao.queryByDatasetId(JSON.toJSONString(map)); - if (textClassificationList != null && !textClassificationList.isEmpty()) { - String textClassifications = String.join(",", textClassificationList.stream().map(TextClassification::getName).collect(Collectors.toSet())); - throw new Exception("该数据集版本被自动机器学习文本分类:" + textClassifications + "使用,不能删除,请先删除自动机器学习文本分类"); + HashMap mLQueryMap = new HashMap<>(); + mLQueryMap.put("dataset", map); + List machineLearnList = machineLearnDao.queryByDatasetId(JSON.toJSONString(mLQueryMap)); + + if (machineLearnList != null && !machineLearnList.isEmpty()) { + String autoMls = String.join(",", machineLearnList.stream().map(MachineLearn::getName).collect(Collectors.toSet())); + throw new Exception("该数据集版本被自动机器学习:" + autoMls + "使用,不能删除,请先删除自动机器学习"); } List rayList = rayDao.queryByDatasetId(JSON.toJSONString(map)); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/TextClassificationInsServiceImpl.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/TextClassificationInsServiceImpl.java index afdd779f..72f0fea1 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/TextClassificationInsServiceImpl.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/impl/TextClassificationInsServiceImpl.java @@ -249,7 +249,7 @@ public class TextClassificationInsServiceImpl implements TextClassificationInsSe statusList.add(insList.get(i).getStatus()); } String subStatus = statusList.toString().substring(1, statusList.toString().length() - 1); - TextClassification textClassification = textClassificationDao.getById(new Long(textClassificationId)); + TextClassification textClassification = textClassificationDao.getById(textClassificationId); if (!StringUtils.equals(textClassification.getStatusList(), subStatus)) { textClassification.setStatusList(subStatus); diff --git a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/TextClassificationParamVo.java b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/TextClassificationParamVo.java index 84f7060a..26d60204 100644 --- a/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/TextClassificationParamVo.java +++ b/ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/vo/TextClassificationParamVo.java @@ -28,4 +28,6 @@ public class TextClassificationParamVo { @ApiModelProperty(value = "学习率") private Float lr; + + private Integer computingResourceId; } diff --git a/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnDaoMapper.xml b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnDaoMapper.xml new file mode 100644 index 00000000..8f5cfe49 --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnDaoMapper.xml @@ -0,0 +1,82 @@ + + + + + + + + + + insert into machine_learn(name, description, type, param, create_by, update_by) + values (#{machineLearn.name}, #{machineLearn.description}, #{machineLearn.type}, + #{machineLearn.param}, #{machineLearn.createBy}, #{machineLearn.updateBy}) + + + + update machine_learn + + + name = #{machineLearn.name}, + + + description = #{machineLearn.description}, + + + type = #{machineLearn.type}, + + + param = #{machineLearn.param}, + + + status_list = #{machineLearn.statusList}, + + + state = #{machineLearn.state}, + + + update_by = #{machineLearn.updateBy}, + + + where id = #{machineLearn.id} + + + + + + + + + + + + + and name like concat('%', #{name}, '%') + + + and type = #{type} + + and state = 1 + + + \ No newline at end of file diff --git a/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnInsDaoMapper.xml b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnInsDaoMapper.xml new file mode 100644 index 00000000..be1b642b --- /dev/null +++ b/ruoyi-modules/management-platform/src/main/resources/mapper/managementPlatform/MachineLearnInsDaoMapper.xml @@ -0,0 +1,83 @@ + + + + + insert into machine_learn_ins(machine_learn_id, type, result_path, model_path, img_path, run_history_path, node_status, + node_result, param, argo_ins_name, argo_ins_ns, status) + values (#{machineLearnIns.machineLearnId}, #{machineLearnIns.type}, #{machineLearnIns.resultPath}, #{machineLearnIns.modelPath}, #{machineLearnIns.imgPath}, + #{machineLearnIns.runHistoryPath}, #{machineLearnIns.nodeStatus}, + #{machineLearnIns.nodeResult}, #{machineLearnIns.param},#{machineLearnIns.argoInsName}, + #{machineLearnIns.argoInsNs}, #{machineLearnIns.status} + ) + + + + update machine_learn_ins + + + type = #{machineLearnIns.type}, + + + status = #{machineLearnIns.status}, + + + state = #{machineLearnIns.state}, + + + update_time = #{machineLearnIns.updateTime}, + + + finish_time = #{machineLearnIns.finishTime}, + + + node_status = #{machineLearnIns.nodeStatus}, + + + node_result = #{machineLearnIns.nodeResult}, + + + where id = #{machineLearnIns.id} + + + + + + + + + + + + \ No newline at end of file