Package org.optaplanner.core.api.solver

## Interface SolverManager<Solution_,​ProblemId_>

- Type Parameters:
    `Solution_` - the solution type, the class with the `PlanningSolution` annotation
    `ProblemId_` - the ID type of a submitted problem, such as `Long` or `UUID`.
  All Superinterfaces:
    `AutoCloseable`
  All Known Implementing Classes:
    `DefaultSolverManager`

      public interface SolverManager<Solution_,​ProblemId_>
      extends AutoCloseable

  A SolverManager solves multiple planning problems of the same domain, asynchronously without blocking the calling thread.

  To create a SolverManager, use `create(SolverFactory, SolverManagerConfig)`. To solve a planning problem, call `solve(Object, Function, Consumer)` or `solveAndListen(Object, Function, Consumer)`.

  These methods are thread-safe unless explicitly stated otherwise.

  Internally a SolverManager manages a thread pool of solver threads (which call `Solver.solve(Object)`) and consumer threads (to handle the `BestSolutionChangedEvent`s).

- - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `close()` | Terminates all solvers, cancels all solver jobs that haven't (re)started yet and discards all queued `ProblemFactChange`s.
    `static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_>` | `create​(SolverFactory<Solution_> solverFactory)` | Use a `SolverFactory` to build a `SolverManager`.
    `static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_>` | `create​(SolverFactory<Solution_> solverFactory, SolverManagerConfig solverManagerConfig)` | Use a `SolverFactory` and a `SolverManagerConfig` to build a `SolverManager`.
    `static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_>` | `create​(SolverConfig solverConfig)` | Use a `SolverConfig` to build a `SolverManager`.
    `static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_>` | `create​(SolverConfig solverConfig, SolverManagerConfig solverManagerConfig)` | Use a `SolverConfig` and a `SolverManagerConfig` to build a `SolverManager`.
    `SolverStatus` | `getSolverStatus​(ProblemId_ problemId)` | Returns if the `Solver` is scheduled to solve, actively solving or not.
    `default SolverJob<Solution_,​ProblemId_>` | `solve​(ProblemId_ problemId, Function<? super ProblemId_,​? extends Solution_> problemFinder, Consumer<? super Solution_> finalBestSolutionConsumer)` | Submits a planning problem to solve and returns immediately.
    `SolverJob<Solution_,​ProblemId_>` | `solve​(ProblemId_ problemId, Function<? super ProblemId_,​? extends Solution_> problemFinder, Consumer<? super Solution_> finalBestSolutionConsumer, BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)` | As defined by `solve(Object, Function, Consumer)`.
    `default SolverJob<Solution_,​ProblemId_>` | `solve​(ProblemId_ problemId, Solution_ problem)` | Submits a planning problem to solve and returns immediately.
    `default SolverJob<Solution_,​ProblemId_>` | `solve​(ProblemId_ problemId, Solution_ problem, Consumer<? super Solution_> finalBestSolutionConsumer)` | As defined by `solve(Object, Object)`.
    `default SolverJob<Solution_,​ProblemId_>` | `solve​(ProblemId_ problemId, Solution_ problem, Consumer<? super Solution_> finalBestSolutionConsumer, BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)` | As defined by `solve(Object, Object)`.
    `default SolverJob<Solution_,​ProblemId_>` | `solveAndListen​(ProblemId_ problemId, Function<? super ProblemId_,​? extends Solution_> problemFinder, Consumer<? super Solution_> bestSolutionConsumer)` | Submits a planning problem to solve and returns immediately.
    `default SolverJob<Solution_,​ProblemId_>` | `solveAndListen​(ProblemId_ problemId, Function<? super ProblemId_,​? extends Solution_> problemFinder, Consumer<? super Solution_> bestSolutionConsumer, BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)` | As defined by `solveAndListen(Object, Function, Consumer)`.
    `SolverJob<Solution_,​ProblemId_>` | `solveAndListen​(ProblemId_ problemId, Function<? super ProblemId_,​? extends Solution_> problemFinder, Consumer<? super Solution_> bestSolutionConsumer, Consumer<? super Solution_> finalBestSolutionConsumer, BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)` | As defined by `solveAndListen(Object, Function, Consumer)`.
    `void` | `terminateEarly​(ProblemId_ problemId)` | Terminates the solver or cancels the solver job if it hasn't (re)started yet.

- - ### Method Detail

    - #### create

          static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_> create​(SolverConfig solverConfig)

      Use a `SolverConfig` to build a `SolverManager`.

      When using `ScoreManager` too, use `create(SolverFactory)` instead so they reuse the same `SolverFactory` instance.

      Type Parameters:
        `Solution_` - the solution type, the class with the `PlanningSolution` annotation
        `ProblemId_` - the ID type of a submitted problem, such as `Long` or `UUID`
      Parameters:
        `solverConfig` - never null
      Returns:
        never null

    - #### create

          static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_> create​(SolverConfig solverConfig,
                                                                                               SolverManagerConfig solverManagerConfig)

      Use a `SolverConfig` and a `SolverManagerConfig` to build a `SolverManager`.

      When using `ScoreManager` too, use `create(SolverFactory, SolverManagerConfig)` instead so they reuse the same `SolverFactory` instance.

      Type Parameters:
        `Solution_` - the solution type, the class with the `PlanningSolution` annotation
        `ProblemId_` - the ID type of a submitted problem, such as `Long` or `UUID`.
      Parameters:
        `solverConfig` - never null
        `solverManagerConfig` - never null
      Returns:
        never null

    - #### create

          static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_> create​(SolverFactory<Solution_> solverFactory)

      Use a `SolverFactory` to build a `SolverManager`.
      Type Parameters:
        `Solution_` - the solution type, the class with the `PlanningSolution` annotation
        `ProblemId_` - the ID type of a submitted problem, such as `Long` or `UUID`
      Parameters:
        `solverFactory` - never null
      Returns:
        never null

    - #### create

          static <Solution_,​ProblemId_> SolverManager<Solution_,​ProblemId_> create​(SolverFactory<Solution_> solverFactory,
                                                                                               SolverManagerConfig solverManagerConfig)

      Use a `SolverFactory` and a `SolverManagerConfig` to build a `SolverManager`.
      Type Parameters:
        `Solution_` - the solution type, the class with the `PlanningSolution` annotation
        `ProblemId_` - the ID type of a submitted problem, such as `Long` or `UUID`.
      Parameters:
        `solverFactory` - never null
        `solverManagerConfig` - never null
      Returns:
        never null

    - #### solve

          default SolverJob<Solution_,​ProblemId_> solve​(ProblemId_ problemId,
                                                              Solution_ problem)

      Submits a planning problem to solve and returns immediately. The planning problem is solved on a solver `Thread`, as soon as one is available. To retrieve the final best solution, use `SolverJob.getFinalBestSolution()`.

      In server applications, it's recommended to use `solve(Object, Function, Consumer)` instead, to avoid loading the problem going stale if solving can't start immediately. To listen to intermediate best solutions too, use `solveAndListen(Object, Function, Consumer)` instead.

      Defaults to logging exceptions as an error.

      To stop a solver job before it naturally terminates, call `SolverJob.terminateEarly()`.

      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early,
        `problem` - never null, a `PlanningSolution` usually with uninitialized planning variables
      Returns:
        never null

    - #### solve

          default SolverJob<Solution_,​ProblemId_> solve​(ProblemId_ problemId,
                                                              Solution_ problem,
                                                              Consumer<? super Solution_> finalBestSolutionConsumer)

      As defined by `solve(Object, Object)`.
      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problem` - never null, a `PlanningSolution` usually with uninitialized planning variables
        `finalBestSolutionConsumer` - sometimes null, called only once, at the end, on a consumer thread
      Returns:
        never null

    - #### solve

          default SolverJob<Solution_,​ProblemId_> solve​(ProblemId_ problemId,
                                                              Solution_ problem,
                                                              Consumer<? super Solution_> finalBestSolutionConsumer,
                                                              BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)

      As defined by `solve(Object, Object)`.
      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problem` - never null, a `PlanningSolution` usually with uninitialized planning variables
        `finalBestSolutionConsumer` - sometimes null, called only once, at the end, on a consumer thread
        `exceptionHandler` - sometimes null, called if an exception or error occurs. If null it defaults to logging the exception as an error.
      Returns:
        never null

    - #### solve

          default SolverJob<Solution_,​ProblemId_> solve​(ProblemId_ problemId,
                                                              Function<? super ProblemId_,​? extends Solution_> problemFinder,
                                                              Consumer<? super Solution_> finalBestSolutionConsumer)

      Submits a planning problem to solve and returns immediately. The planning problem is solved on a solver `Thread`, as soon as one is available.

      When the solver terminates, the `finalBestSolutionConsumer` is called once with the final best solution, on a consumer `Thread`, as soon as one is available. To listen to intermediate best solutions too, use `solveAndListen(Object, Function, Consumer)` instead.

      Defaults to logging exceptions as an error.

      To stop a solver job before it naturally terminates, call `terminateEarly(Object)`.

      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problemFinder` - never null, a function that returns a `PlanningSolution`, usually with uninitialized planning variables
        `finalBestSolutionConsumer` - sometimes null, called only once, at the end, on a consumer thread
      Returns:
        never null

    - #### solve

          SolverJob<Solution_,​ProblemId_> solve​(ProblemId_ problemId,
                                                      Function<? super ProblemId_,​? extends Solution_> problemFinder,
                                                      Consumer<? super Solution_> finalBestSolutionConsumer,
                                                      BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)

      As defined by `solve(Object, Function, Consumer)`.
      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problemFinder` - never null, function that returns a `PlanningSolution`, usually with uninitialized planning variables
        `finalBestSolutionConsumer` - sometimes null, called only once, at the end, on a consumer thread
        `exceptionHandler` - sometimes null, called if an exception or error occurs. If null it defaults to logging the exception as an error.
      Returns:
        never null

    - #### solveAndListen

          default SolverJob<Solution_,​ProblemId_> solveAndListen​(ProblemId_ problemId,
                                                                       Function<? super ProblemId_,​? extends Solution_> problemFinder,
                                                                       Consumer<? super Solution_> bestSolutionConsumer)

      Submits a planning problem to solve and returns immediately. The planning problem is solved on a solver `Thread`, as soon as one is available.

      When the solver finds a new best solution, the `bestSolutionConsumer` is called every time, on a consumer `Thread`, as soon as one is available (taking into account any throttling waiting time), unless a newer best solution is already available by then (in which case skip ahead discards it).

      Defaults to logging exceptions as an error.

      To stop a solver job before it naturally terminates, call `terminateEarly(Object)`.

      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problemFinder` - never null, a function that returns a `PlanningSolution`, usually with uninitialized planning variables
        `bestSolutionConsumer` - never null, called multiple times, on a consumer thread
      Returns:
        never null

    - #### solveAndListen

          default SolverJob<Solution_,​ProblemId_> solveAndListen​(ProblemId_ problemId,
                                                                       Function<? super ProblemId_,​? extends Solution_> problemFinder,
                                                                       Consumer<? super Solution_> bestSolutionConsumer,
                                                                       BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)

      As defined by `solveAndListen(Object, Function, Consumer)`.
      Parameters:
        `problemId` - never null, a ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problemFinder` - never null, function that returns a `PlanningSolution`, usually with uninitialized planning variables
        `bestSolutionConsumer` - never null, called multiple times, on a consumer thread
        `exceptionHandler` - sometimes null, called if an exception or error occurs. If null it defaults to logging the exception as an error.
      Returns:
        never null

    - #### solveAndListen

          SolverJob<Solution_,​ProblemId_> solveAndListen​(ProblemId_ problemId,
                                                               Function<? super ProblemId_,​? extends Solution_> problemFinder,
                                                               Consumer<? super Solution_> bestSolutionConsumer,
                                                               Consumer<? super Solution_> finalBestSolutionConsumer,
                                                               BiConsumer<? super ProblemId_,​? super Throwable> exceptionHandler)

      As defined by `solveAndListen(Object, Function, Consumer)`.

      The final best solution is delivered twice: first to the `bestSolutionConsumer` when it is found and then again to the `finalBestSolutionConsumer` when the solver terminates. Do not store the solution twice. This allows for use cases that only process the `Score` first (during best solution changed events) and then store the solution upon termination.

      Parameters:
        `problemId` - never null, an ID for each planning problem. This must be unique. Use this problemId to `terminate` the solver early, `to get the status` or if the problem changes while solving.
        `problemFinder` - never null, function that returns a `PlanningSolution`, usually with uninitialized planning variables
        `bestSolutionConsumer` - never null, called multiple times, on a consumer thread
        `finalBestSolutionConsumer` - sometimes null, called only once, at the end, on a consumer thread. That final best solution is already consumed by the bestSolutionConsumer earlier.
        `exceptionHandler` - sometimes null, called if an exception or error occurs. If null it defaults to logging the exception as an error.
      Returns:
        never null

    - #### getSolverStatus

          SolverStatus getSolverStatus​(ProblemId_ problemId)

      Returns if the `Solver` is scheduled to solve, actively solving or not.

      Returns `SolverStatus.NOT_SOLVING` if the solver already terminated or if the problemId was never added. To distinguish between both cases, use `SolverJob.getSolverStatus()` instead. Here, that distinction is not supported because it would cause a memory leak.

      Parameters:
        `problemId` - never null, a value given to `solve(Object, Function, Consumer)` or `solveAndListen(Object, Function, Consumer)`
      Returns:
        never null

    - #### terminateEarly

          void terminateEarly​(ProblemId_ problemId)

      Terminates the solver or cancels the solver job if it hasn't (re)started yet.

      Does nothing if the solver already terminated or the problemId was never added. To distinguish between both cases, use `SolverJob.terminateEarly()` instead. Here, that distinction is not supported because it would cause a memory leak.

      Waits for the termination or cancellation to complete before returning. During termination, a `bestSolutionConsumer` could still be called (on a consumer thread), before this method returns.

      Parameters:
        `problemId` - never null, a value given to `solve(Object, Function, Consumer)` or `solveAndListen(Object, Function, Consumer)`

    - #### close

          void close()

      Terminates all solvers, cancels all solver jobs that haven't (re)started yet and discards all queued `ProblemFactChange`s. Releases all thread pool resources.

      No new planning problems can be submitted after calling this method.

      Specified by:
        `close` in interface `AutoCloseable`