Commit d5696b02 by 张晓

增加异步调用方式

1 parent 512dd5f6
...@@ -6,23 +6,23 @@ import com.dituhui.pea.common.Result; ...@@ -6,23 +6,23 @@ import com.dituhui.pea.common.Result;
import com.dituhui.pea.pre.opta.domain.Customer; import com.dituhui.pea.pre.opta.domain.Customer;
import com.dituhui.pea.pre.opta.domain.Vehicle; import com.dituhui.pea.pre.opta.domain.Vehicle;
import com.dituhui.pea.pre.opta.domain.VehicleRoutingSolution; import com.dituhui.pea.pre.opta.domain.VehicleRoutingSolution;
import com.dituhui.pea.pre.service.BatchService; import com.dituhui.pea.pre.opta.solver.VehicleRoutingConstraintProvider;
import com.dituhui.pea.pre.service.PrepareService; import com.dituhui.pea.pre.service.PrepareService;
import com.dituhui.pea.pre.service.SolveService; import com.dituhui.pea.pre.service.SolveService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore; import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.api.solver.SolverManager;
import org.optaplanner.core.api.solver.SolverStatus;
import org.optaplanner.core.config.solver.SolverConfig;
import org.optaplanner.core.config.solver.SolverManagerConfig;
import org.optaplanner.core.impl.solver.DefaultSolverManager;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLException; import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
/** /**
* @author zhangx * @author zhangx
...@@ -39,6 +39,19 @@ public class PrepareController { ...@@ -39,6 +39,19 @@ public class PrepareController {
@Autowired @Autowired
SolveService solveService; SolveService solveService;
private SolverManager<VehicleRoutingSolution, UUID> solverManager;
public PrepareController() {
SolverConfig solverConfig = new SolverConfig();
solverConfig.withSolutionClass(VehicleRoutingSolution.class);
solverConfig.withEntityClasses(Vehicle.class);
solverConfig.withConstraintProviderClass(VehicleRoutingConstraintProvider.class);
// solverConfig.with
solverManager= SolverManager.create(solverConfig, new SolverManagerConfig());
}
/* /*
* 检查指定日期的小组是否有在运行的批次任务,有则返回,没有则创建后返回批次码 * 检查指定日期的小组是否有在运行的批次任务,有则返回,没有则创建后返回批次码
*/ */
...@@ -59,34 +72,37 @@ public class PrepareController { ...@@ -59,34 +72,37 @@ public class PrepareController {
// 异步任务运行 todo // 异步任务运行 todo
@GetMapping("/prepare/solveAsync/{groupId}/{batchNo}") @GetMapping("/prepare/solveAsync/{groupId}/{batchNo}")
public Result<?> solveAsync(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> solveAsync(@PathVariable String groupId, @PathVariable String batchNo) {
log.info("solveAsync, groupId:{}, day:{}", groupId, batchNo); log.info("调用引擎处理-异步处理, groupId:{}, batchNo:{}", groupId, batchNo);
VehicleRoutingSolution solution = null; UUID problemId = solveService.generateProblemId(groupId, batchNo);
try { // 提交问题开始求解
solution = solveService.solveAsync(groupId, batchNo); VehicleRoutingSolution problem= solveService.prepareSolution(groupId, batchNo);
prepareService.saveSolutionToDispatch(groupId, batchNo, solution);
prepareService.extractDispatchToOrder(groupId, batchNo);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}
HardSoftLongScore score = solution.getScore();
log.info("solveAsync done, groupId:{}, day:{}, score:{}", groupId, batchNo, score.toString()); solverManager.solveAndListen(problemId, id -> problem,
this.prepareService::saveSolutionToDispatch);
return Result.success(score); log.error("调用引擎处理-异步处理, 已触发异步, groupId:{}, batchNo:{}", groupId, batchNo);
return Result.success("已触发异步执行");
} }
@GetMapping("/prepare/solveStatus/{groupId}/{batchNo}") @GetMapping("/prepare/solveStatus/{groupId}/{batchNo}")
public Result<?> solveStatus(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> solveStatus(@PathVariable String groupId, @PathVariable String batchNo) {
return Result.success( solveService.status(groupId, batchNo)); log.info("查询引擎处理状态, groupId:{}, batchNo:{}", groupId, batchNo);
UUID problemId = solveService.generateProblemId(groupId, batchNo);
SolverStatus status = solverManager.getSolverStatus(problemId);
log.info("查询引擎处理状态, groupId:{}, batchNo:{}, status:{}", groupId, batchNo, status.toString());
return Result.success(status);
} }
@GetMapping("/prepare/solveStop/{groupId}/{batchNo}") @GetMapping("/prepare/solveStop/{groupId}/{batchNo}")
public Result<?> solveStop(@PathVariable String groupId, @PathVariable String batchNo) { public Result<?> solveStop(@PathVariable String groupId, @PathVariable String batchNo) {
return Result.success( solveService.stopSolving(groupId, batchNo)); log.info("停止引擎处理批次, groupId:{}, batchNo:{}", groupId, batchNo);
UUID problemId = solveService.generateProblemId(groupId, batchNo);
solverManager.terminateEarly(problemId);
SolverStatus status = solverManager.getSolverStatus(problemId);
log.info("停止引擎处理批次, groupId:{}, batchNo:{}, status:{}", groupId, batchNo, status.toString());
return Result.success(status);
} }
} }
......
...@@ -4,9 +4,9 @@ package com.dituhui.pea.pre.entity; ...@@ -4,9 +4,9 @@ package com.dituhui.pea.pre.entity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import javax.persistence.*;
/** /**
* 排班批次总表 * 排班批次总表
......
package com.dituhui.pea.pre.interceptor; package com.dituhui.pea.pre.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
...@@ -10,7 +11,6 @@ import org.springframework.web.context.request.RequestContextHolder; ...@@ -10,7 +11,6 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
@Slf4j @Slf4j
@Aspect @Aspect
...@@ -19,7 +19,7 @@ public class RequestInterceptor implements HandlerInterceptor { ...@@ -19,7 +19,7 @@ public class RequestInterceptor implements HandlerInterceptor {
/** /**
* 以 controller 包下定义的所有请求为切入点 * 以 controller 包下定义的所有请求为切入点
*/ */
@Pointcut(value = "execution(public * com.dituhui.pea.order.controller..*.*(..))") @Pointcut(value = "execution(public * com.dituhui.pea.pre.controller..*.*(..))")
public void reqOpenAPILog() { public void reqOpenAPILog() {
} }
......
...@@ -7,13 +7,14 @@ import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty; ...@@ -7,13 +7,14 @@ import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider; import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore; import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@PlanningSolution @PlanningSolution
public class VehicleRoutingSolution { public class VehicleRoutingSolution {
private String name; private String groupId;
private String batchNo;
@ProblemFactCollectionProperty @ProblemFactCollectionProperty
private List<Location> locationList; private List<Location> locationList;
...@@ -35,10 +36,10 @@ public class VehicleRoutingSolution { ...@@ -35,10 +36,10 @@ public class VehicleRoutingSolution {
public VehicleRoutingSolution() { public VehicleRoutingSolution() {
} }
public VehicleRoutingSolution(String name, List<Depot> depotList, List<Vehicle> vehicleList, public VehicleRoutingSolution(String groupId, String batchNo, List<Depot> depotList, List<Vehicle> vehicleList,
List<Customer> customerList, List<Location> locationList) { List<Customer> customerList, List<Location> locationList) {
this.name = name; this.groupId = groupId;
this.batchNo = batchNo;
this.depotList = depotList; this.depotList = depotList;
this.vehicleList = vehicleList; this.vehicleList = vehicleList;
this.customerList = customerList; this.customerList = customerList;
...@@ -46,12 +47,20 @@ public class VehicleRoutingSolution { ...@@ -46,12 +47,20 @@ public class VehicleRoutingSolution {
} }
public String getName() { public String getGroupId() {
return name; return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getBatchNo() {
return batchNo;
} }
public void setName(String name) { public void setBatchNo(String batchNo) {
this.name = name; this.batchNo = batchNo;
} }
public List<Location> getLocationList() { public List<Location> getLocationList() {
......
...@@ -19,7 +19,7 @@ public interface PrepareService { ...@@ -19,7 +19,7 @@ public interface PrepareService {
/* /*
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间) * 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
* */ * */
void saveSolutionToDispatch(String groupId, String batchNo, VehicleRoutingSolution solution) throws SQLException; void saveSolutionToDispatch(VehicleRoutingSolution solution) throws RuntimeException;
/* /*
* 将dispath_order 中的计算结果,回写到 order_request, order_appointment * 将dispath_order 中的计算结果,回写到 order_request, order_appointment
......
...@@ -25,11 +25,7 @@ public interface SolveService { ...@@ -25,11 +25,7 @@ public interface SolveService {
UUID generateProblemId(String groupId, String batchNo); UUID generateProblemId(String groupId, String batchNo);
VehicleRoutingSolution solveAsync(String groupId, String batchNo) throws ExecutionException, InterruptedException; VehicleRoutingSolution prepareSolution(String groupId, String batchNo) ;
SolverStatus status(String groupId, String batchNo);
SolverStatus stopSolving(String groupId, String batchNo);
} }
...@@ -48,12 +48,10 @@ public class PrepareServiceImpl implements PrepareService { ...@@ -48,12 +48,10 @@ public class PrepareServiceImpl implements PrepareService {
} }
@Autowired @Autowired
EngineerInfoRepository engineerInfoRepo; EngineerInfoRepository engineerInfoRepo;
@Autowired @Autowired
DispatchOrderRepository dispatchOrderRepo; DispatchOrderRepository dispatchOrderRepo;
...@@ -64,18 +62,24 @@ public class PrepareServiceImpl implements PrepareService { ...@@ -64,18 +62,24 @@ public class PrepareServiceImpl implements PrepareService {
OrderAppointmentRepository orderAppointmentRepo; OrderAppointmentRepository orderAppointmentRepo;
/** /**
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间) * 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
*/ */
@Override @Override
public void saveSolutionToDispatch(String groupId, String batchNo, VehicleRoutingSolution solution) throws SQLException { public void saveSolutionToDispatch(VehicleRoutingSolution solution) throws RuntimeException {
String groupId = solution.getGroupId();
String batchNo = solution.getBatchNo();
log.info("算法结果回写, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果回写, groupId:{}, batchNo:{}", groupId, batchNo);
// 清理当前批次指派结果 // 清理当前批次指派结果
log.info("算法结果回写, step1-清除历史, groupId:{}, batchNo:{}", groupId, batchNo); log.info("算法结果回写, step1-清除历史, groupId:{}, batchNo:{}", groupId, batchNo);
Object[] paramClear = {groupId, batchNo}; Object[] paramClear = {groupId, batchNo};
try {
queryRunner.update(" update dispatch_order set engineer_code='' , seq=0, time_begin=null ,time_end=null where group_id=? and batch_no=? ", paramClear); queryRunner.update(" update dispatch_order set engineer_code='' , seq=0, time_begin=null ,time_end=null where group_id=? and batch_no=? ", paramClear);
} catch (SQLException e) {
log.info("算法结果回写, step1-清除历史异常, groupId:{}, batchNo:{}", groupId, batchNo);
throw new RuntimeException(e);
}
String sql = "update dispatch_order set engineer_code=? , seq=?, time_begin=? ,time_end=? where group_id=? and batch_no=? and order_id=? "; String sql = "update dispatch_order set engineer_code=? , seq=?, time_begin=? ,time_end=? where group_id=? and batch_no=? and order_id=? ";
...@@ -239,6 +243,4 @@ public class PrepareServiceImpl implements PrepareService { ...@@ -239,6 +243,4 @@ public class PrepareServiceImpl implements PrepareService {
} }
} }
...@@ -6,6 +6,7 @@ import com.dituhui.pea.pre.dao.DispatchOrderRepository; ...@@ -6,6 +6,7 @@ import com.dituhui.pea.pre.dao.DispatchOrderRepository;
import com.dituhui.pea.pre.opta.domain.*; import com.dituhui.pea.pre.opta.domain.*;
import com.dituhui.pea.pre.opta.domain.geo.DistanceCalculator; import com.dituhui.pea.pre.opta.domain.geo.DistanceCalculator;
import com.dituhui.pea.pre.opta.solver.VehicleRoutingConstraintProvider; import com.dituhui.pea.pre.opta.solver.VehicleRoutingConstraintProvider;
import com.dituhui.pea.pre.service.PrepareService;
import com.dituhui.pea.pre.service.SolveService; import com.dituhui.pea.pre.service.SolveService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.QueryRunner;
...@@ -41,12 +42,12 @@ public class SolveServiceImpl implements SolveService { ...@@ -41,12 +42,12 @@ public class SolveServiceImpl implements SolveService {
@Autowired @Autowired
DispatchOrderRepository dispatchOrderRepo; DispatchOrderRepository dispatchOrderRepo;
@Autowired
PrepareService prepareService;
private QueryRunner queryRunner; private QueryRunner queryRunner;
@Autowired
private SolverManager<VehicleRoutingSolution, UUID> solverManager;
@Autowired
private SolutionManager<VehicleRoutingSolution, HardSoftScore> solutionManager;
public SolveServiceImpl(DataSource dataSource) { public SolveServiceImpl(DataSource dataSource) {
...@@ -69,7 +70,8 @@ public class SolveServiceImpl implements SolveService { ...@@ -69,7 +70,8 @@ public class SolveServiceImpl implements SolveService {
// 按小组、批次号组装问题对象 // 按小组、批次号组装问题对象
private VehicleRoutingSolution prepareSolution(String groupId, String batchNo) { @Override
public VehicleRoutingSolution prepareSolution(String groupId, String batchNo) {
log.info("组织问题对象, groupId:{}, batchNo:{}", groupId, batchNo); log.info("组织问题对象, groupId:{}, batchNo:{}", groupId, batchNo);
// depotlist // depotlist
ArrayList<Depot> depotList = new ArrayList<Depot>(); ArrayList<Depot> depotList = new ArrayList<Depot>();
...@@ -107,7 +109,7 @@ public class SolveServiceImpl implements SolveService { ...@@ -107,7 +109,7 @@ public class SolveServiceImpl implements SolveService {
//locationlist //locationlist
List<Location> locationList = Stream.concat(depotList.stream().map(Depot::getLocation), customerList.stream().map(Customer::getLocation)).collect(Collectors.toList()); List<Location> locationList = Stream.concat(depotList.stream().map(Depot::getLocation), customerList.stream().map(Customer::getLocation)).collect(Collectors.toList());
VehicleRoutingSolution solution = new VehicleRoutingSolution(groupId, depotList, vehicleList, customerList, locationList); VehicleRoutingSolution solution = new VehicleRoutingSolution(groupId, batchNo, depotList, vehicleList, customerList, locationList);
distanceCalculator.initDistanceMaps(locationList); distanceCalculator.initDistanceMaps(locationList);
log.info("组织问题对象, groupId:{}, batchNo:{}, employ-centerpoi-size:{}, employ-size:{}, customer-size:{}, center-location-size:{}", groupId, batchNo, depotList.size(), vehicleList.size(), customerList.size(), locationList.size()); log.info("组织问题对象, groupId:{}, batchNo:{}, employ-centerpoi-size:{}, employ-size:{}, customer-size:{}, center-location-size:{}", groupId, batchNo, depotList.size(), vehicleList.size(), customerList.size(), locationList.size());
...@@ -152,38 +154,4 @@ public class SolveServiceImpl implements SolveService { ...@@ -152,38 +154,4 @@ public class SolveServiceImpl implements SolveService {
return uid; return uid;
} }
public VehicleRoutingSolution solveAsync(String groupId, String batchNo) throws ExecutionException, InterruptedException {
log.info("调用引擎处理-异步处理, groupId:{}, batchNo:{}", groupId, batchNo);
UUID problemId = generateProblemId(groupId, batchNo);
VehicleRoutingSolution problem = prepareSolution(groupId, batchNo);
// 提交问题开始求解
SolverJob<VehicleRoutingSolution, UUID> solverJob = solverManager.solve(problemId, problem);
VehicleRoutingSolution solution;
// 等待求解结束
solution = solverJob.getFinalBestSolution();
log.info("调用引擎处理-异步处理结果, groupId:{}, batchNo:{}, result:{}", groupId, batchNo, solution.getScore().toString());
return solution;
}
@Override
public SolverStatus status(String groupId, String batchNo) {
log.info("查询引擎处理状态, groupId:{}, batchNo:{}", groupId, batchNo);
UUID problemId = generateProblemId(groupId, batchNo);
SolverStatus status = solverManager.getSolverStatus(problemId);
log.info("查询引擎处理状态, groupId:{}, batchNo:{}, status:{}", groupId, batchNo, status.toString());
return status;
}
@Override
public SolverStatus stopSolving(String groupId, String batchNo) {
log.info("停止引擎处理批次, groupId:{}, batchNo:{}", groupId, batchNo);
UUID problemId = generateProblemId(groupId, batchNo);
solverManager.terminateEarly(problemId);
SolverStatus status = solverManager.getSolverStatus(problemId);
log.info("停止引擎处理批次, groupId:{}, batchNo:{}, status:{}", groupId, batchNo, status.toString());
return status;
}
} }
...@@ -13,6 +13,7 @@ import java.sql.SQLException; ...@@ -13,6 +13,7 @@ import java.sql.SQLException;
@Slf4j @Slf4j
@SpringBootTest @SpringBootTest
public class BatchServiceTest { public class BatchServiceTest {
@Autowired @Autowired
BatchService batchService; BatchService batchService;
...@@ -36,6 +37,7 @@ public class BatchServiceTest { ...@@ -36,6 +37,7 @@ public class BatchServiceTest {
public void test2() { public void test2() {
log.info("init"); log.info("init");
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
String orderNO= IdUtil.getSnowflake().nextIdStr(); String orderNO= IdUtil.getSnowflake().nextIdStr();
log.info("oid:{}", orderNO); log.info("oid:{}", orderNO);
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!