12.5. 创建 Timetable 服务
现在,您已准备好将所有内容放在一起,并创建一个 REST 服务。但是,在 REST 线程上计划问题会导致 HTTP 超时问题。因此,Spring Boot Start 注入 SolverManager
,它会在一个单独的线程池中运行 solvers,并可并行解决多个数据集。
流程
创建 src/main/java/com/example/solver/TimeTableController.java
类:
package com.example.solver; import java.util.UUID; import java.util.concurrent.ExecutionException; import com.example.domain.TimeTable; import org.optaplanner.core.api.solver.SolverJob; import org.optaplanner.core.api.solver.SolverManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/timeTable") public class TimeTableController { @Autowired private SolverManager<TimeTable, UUID> solverManager; @PostMapping("/solve") public TimeTable solve(@RequestBody TimeTable problem) { UUID problemId = UUID.randomUUID(); // Submit the problem to start solving SolverJob<TimeTable, UUID> solverJob = solverManager.solve(problemId, problem); TimeTable solution; try { // Wait until the solving ends solution = solverJob.getFinalBestSolution(); } catch (InterruptedException | ExecutionException e) { throw new IllegalStateException("Solving failed.", e); } return solution; } }
package com.example.solver;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import com.example.domain.TimeTable;
import org.optaplanner.core.api.solver.SolverJob;
import org.optaplanner.core.api.solver.SolverManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/timeTable")
public class TimeTableController {
@Autowired
private SolverManager<TimeTable, UUID> solverManager;
@PostMapping("/solve")
public TimeTable solve(@RequestBody TimeTable problem) {
UUID problemId = UUID.randomUUID();
// Submit the problem to start solving
SolverJob<TimeTable, UUID> solverJob = solverManager.solve(problemId, problem);
TimeTable solution;
try {
// Wait until the solving ends
solution = solverJob.getFinalBestSolution();
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("Solving failed.", e);
}
return solution;
}
}
在本例中,初始实施会等待 solver 完成,这仍然可能导致 HTTP 超时。完整的 实现可避免 HTTP 超时更小。