OptaPlanner
  1. OptaPlanner
  2. PLANNER-94

Allow setting a global variable (for example a service) which can be used by the score rules

    Details

    • Type: Feature Request Feature Request
    • Status: Open Open (View Workflow)
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: optaplanner-core
    • Labels:
      None
    • Similar Issues:
      Show 10 results 

      Description

      Currently, it is not possible to set a global variable in the working memory used by the solver. If a scoring rule needs an external helper for calculating scores (e.g. a dependency injected with OSGi DS), a workaround using a static variable in some class accessible by the scoring rules is needed.

      The easiest implementation is probably a new method in the Solver interface: // Impossible
      public WorkingMemory getWorkingMemory();
      which provides access to the working memory used by the solver.
      => Impossible because the number of WorkingMemory equals the number of threads being used by Planner, and sometimes they are reset.

        Issue Links

          Activity

          Hide
          Geoffrey De Smet
          added a comment -

          The main reason why there are multiple WM's in population scenario's and/or multi-threaded solving scenario's (neither which have been implemented today), is because of incremental score calculation (see manual).

          Show
          Geoffrey De Smet
          added a comment - The main reason why there are multiple WM's in population scenario's and/or multi-threaded solving scenario's (neither which have been implemented today), is because of incremental score calculation (see manual).
          Hide
          Henrik Saksela
          added a comment -

          Yeah I noticed the part about creating new WMs between phases; my first attempt att solving this crudely injected the globals into the initial WM which worked until the first phase ended.. Overriding the WM creation in RuleBase worked, but it wasn't a very elegant solution

          Still, if the globals were notified 1) at the beginning / end of solve() at this point, 2) at the beginning / end of any spawned threads in the future, they could take care of the their own thread safety using threadlocals. Of course, as long as planner isn't multithreaded I can just implement the thread-specific stuff outside solver..

          Show
          Henrik Saksela
          added a comment - Yeah I noticed the part about creating new WMs between phases; my first attempt att solving this crudely injected the globals into the initial WM which worked until the first phase ended.. Overriding the WM creation in RuleBase worked, but it wasn't a very elegant solution Still, if the globals were notified 1) at the beginning / end of solve() at this point, 2) at the beginning / end of any spawned threads in the future, they could take care of the their own thread safety using threadlocals. Of course, as long as planner isn't multithreaded I can just implement the thread-specific stuff outside solver..
          Hide
          Geoffrey De Smet
          added a comment -

          Solution proposal D: Notifying the globals at the beginning and ending of workingMemory creation (not solve())
          I don't prefer this proposal, because it requires the global instances to implement a custom interface, so you can't reuse JDCB's datasource directly etc.

          Solution proposal E: Notify a WorkingMemoryManager interface from DroolsScoreDirectorFactory every time a WM is created or destroyed.
          This is basically proposal B. I think I prefer this one.

          How to do proposal E:
          DroolsScoreDirector must delegate WM creation and destruction to DroolsScoreDirectorFactory
          DroolsScoreDirectorFactory can have a WorkingMemoryManager instance.
          Upon WM creation and destruction, DroolsScoreDirectorFactory calls WorkingMemoryManager.
          This gives WorkingMemoryManager an opportunity to add globals (and whatnot) to the WM during creation and cleanup during destruction.

          Show
          Geoffrey De Smet
          added a comment - Solution proposal D: Notifying the globals at the beginning and ending of workingMemory creation (not solve()) I don't prefer this proposal, because it requires the global instances to implement a custom interface, so you can't reuse JDCB's datasource directly etc. Solution proposal E: Notify a WorkingMemoryManager interface from DroolsScoreDirectorFactory every time a WM is created or destroyed. This is basically proposal B. I think I prefer this one. How to do proposal E: DroolsScoreDirector must delegate WM creation and destruction to DroolsScoreDirectorFactory DroolsScoreDirectorFactory can have a WorkingMemoryManager instance. Upon WM creation and destruction, DroolsScoreDirectorFactory calls WorkingMemoryManager. This gives WorkingMemoryManager an opportunity to add globals (and whatnot) to the WM during creation and cleanup during destruction.
          Hide
          Henrik Saksela
          added a comment -

          Yes, Solution E does sound the most elegant. I'll see what implementing this would entail / look into doing a pull request. Thanks for your time!

          Show
          Henrik Saksela
          added a comment - Yes, Solution E does sound the most elegant. I'll see what implementing this would entail / look into doing a pull request. Thanks for your time!
          Hide
          Geoffrey De Smet
          added a comment -

          @Henrik thanks! If it's good, I 'll merge it

          Show
          Geoffrey De Smet
          added a comment - @Henrik thanks! If it's good, I 'll merge it

            People

            • Assignee:
              Geoffrey De Smet
              Reporter:
              Wouter Horré
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: