Commit d5696b02 by 张晓

增加异步调用方式

1 parent 512dd5f6
......@@ -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.Vehicle;
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.SolveService;
import lombok.extern.slf4j.Slf4j;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.*;
/**
* @author zhangx
......@@ -39,6 +39,19 @@ public class PrepareController {
@Autowired
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 {
// 异步任务运行 todo
@GetMapping("/prepare/solveAsync/{groupId}/{batchNo}")
public Result<?> solveAsync(@PathVariable String groupId, @PathVariable String batchNo) {
log.info("solveAsync, groupId:{}, day:{}", groupId, batchNo);
VehicleRoutingSolution solution = null;
try {
solution = solveService.solveAsync(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("调用引擎处理-异步处理, groupId:{}, batchNo:{}", groupId, batchNo);
UUID problemId = solveService.generateProblemId(groupId, batchNo);
// 提交问题开始求解
VehicleRoutingSolution problem= solveService.prepareSolution(groupId, batchNo);
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}")
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}")
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;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import javax.persistence.*;
/**
* 排班批次总表
......
package com.dituhui.pea.pre.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
......@@ -10,7 +11,6 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@Aspect
......@@ -19,7 +19,7 @@ public class RequestInterceptor implements HandlerInterceptor {
/**
* 以 controller 包下定义的所有请求为切入点
*/
@Pointcut(value = "execution(public * com.dituhui.pea.order.controller..*.*(..))")
@Pointcut(value = "execution(public * com.dituhui.pea.pre.controller..*.*(..))")
public void reqOpenAPILog() {
}
......
......@@ -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.score.buildin.hardsoftlong.HardSoftLongScore;
import java.util.ArrayList;
import java.util.List;
@PlanningSolution
public class VehicleRoutingSolution {
private String name;
private String groupId;
private String batchNo;
@ProblemFactCollectionProperty
private List<Location> locationList;
......@@ -35,10 +36,10 @@ public class 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) {
this.name = name;
this.groupId = groupId;
this.batchNo = batchNo;
this.depotList = depotList;
this.vehicleList = vehicleList;
this.customerList = customerList;
......@@ -46,12 +47,20 @@ public class VehicleRoutingSolution {
}
public String getName() {
return name;
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getBatchNo() {
return batchNo;
}
public void setName(String name) {
this.name = name;
public void setBatchNo(String batchNo) {
this.batchNo = batchNo;
}
public List<Location> getLocationList() {
......
......@@ -19,7 +19,7 @@ public interface PrepareService {
/*
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
* */
void saveSolutionToDispatch(String groupId, String batchNo, VehicleRoutingSolution solution) throws SQLException;
void saveSolutionToDispatch(VehicleRoutingSolution solution) throws RuntimeException;
/*
* 将dispath_order 中的计算结果,回写到 order_request, order_appointment
......
......@@ -25,11 +25,7 @@ public interface SolveService {
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 {
}
@Autowired
EngineerInfoRepository engineerInfoRepo;
@Autowired
DispatchOrderRepository dispatchOrderRepo;
......@@ -64,18 +62,24 @@ public class PrepareServiceImpl implements PrepareService {
OrderAppointmentRepository orderAppointmentRepo;
/**
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
*/
@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("算法结果回写, step1-清除历史, groupId:{}, batchNo:{}", groupId, batchNo);
Object[] paramClear = {groupId, batchNo};
queryRunner.update(" update dispatch_order set engineer_code='' , seq=0, time_begin=null ,time_end=null where group_id=? and batch_no=? ", paramClear);
try {
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=? ";
......@@ -239,6 +243,4 @@ public class PrepareServiceImpl implements PrepareService {
}
}
......@@ -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.geo.DistanceCalculator;
import com.dituhui.pea.pre.opta.solver.VehicleRoutingConstraintProvider;
import com.dituhui.pea.pre.service.PrepareService;
import com.dituhui.pea.pre.service.SolveService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbutils.QueryRunner;
......@@ -41,12 +42,12 @@ public class SolveServiceImpl implements SolveService {
@Autowired
DispatchOrderRepository dispatchOrderRepo;
@Autowired
PrepareService prepareService;
private QueryRunner queryRunner;
@Autowired
private SolverManager<VehicleRoutingSolution, UUID> solverManager;
@Autowired
private SolutionManager<VehicleRoutingSolution, HardSoftScore> solutionManager;
public SolveServiceImpl(DataSource dataSource) {
......@@ -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);
// depotlist
ArrayList<Depot> depotList = new ArrayList<Depot>();
......@@ -107,7 +109,7 @@ public class SolveServiceImpl implements SolveService {
//locationlist
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);
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 {
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;
@Slf4j
@SpringBootTest
public class BatchServiceTest {
@Autowired
BatchService batchService;
......@@ -36,6 +37,7 @@ public class BatchServiceTest {
public void test2() {
log.info("init");
for (int i = 0; i < 100; i++) {
String orderNO= IdUtil.getSnowflake().nextIdStr();
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!