symbiote / silverstripe-queuedjobs

A module that provides interfaces for scheduling jobs for certain times.
BSD 3-Clause "New" or "Revised" License
57 stars 74 forks source link

Included Doorman DefaultRule config not 'injected' #296

Open micschk opened 4 years ago

micschk commented 4 years ago

This module's queuedjobs.yml contains a default Doorman rule which is supposed to make jobs run one at a time. But this config doesn't seem to get applied correctly, making Doorman run all jobs simultaneously.

The cause of this issue seems to be the order in which the injector properties get applied; I think the current included DefaultRule config somehow does not get applied to the %$DoormanRunner instance set as queueRunner(?)

queuedjobs.yml (included in module)

---
Name: queuedjobsettings
---
SilverStripe\Core\Injector\Injector:
  ...
  DoormanRunner:
    class: Symbiote\QueuedJobs\Tasks\Engines\DoormanRunner

  Symbiote\QueuedJobs\Services\QueuedJobService:
    properties:
      # Change to %$DoormanRunner for async processing (requires *nix)
      queueRunner: %$Symbiote\QueuedJobs\Tasks\Engines\QueueRunner

  DefaultRule:
    class: 'AsyncPHP\Doorman\Rule\InMemoryRule'
    properties:
      Processes: 1
      MinimumProcessorUsage: 0
      MaximumProcessorUsage: 100

  Symbiote\QueuedJobs\Tasks\Engines\DoormanRunner:
    properties:
      DefaultRules:
        - '%$DefaultRule'

When I try to set DoormanRunner in my app config as per the comment in the queuedjobs.yml, the DefaultRules config doesn't get applied (resulting in all jobs starting simultaneously).

app.yml

---
Name: my_app_qjobs
After:
  - '#queuedjobsettings'
---
SilverStripe\Core\Injector\Injector:

  DoormanRunner:
    class: Symbiote\QueuedJobs\Tasks\Engines\DoormanRunner

  Symbiote\QueuedJobs\Services\QueuedJobService:
    properties:
      queueRunner: %$DoormanRunner

This results in an empty array as DefaultRules

        $qjService = Injector::inst()->create(QueuedJobService::class);
        $doorman = $qjService->queueRunner;
        var_dump( $qjService->queueRunner->getDefaultRules() );
        // result: empty array

The below config does apply the DefaultRule correctly (and coincidentally replaces any previously set Defaultrules, probably because a new DoormanRunner instance, along with the correct DefaultRules gets created/injected in QueuedJobService.queueRunner);

---
Name: mailing_qjobs
After:
  - '#queuedjobsettings'
---
SilverStripe\Core\Injector\Injector:

  DefaultRule:
    class: 'AsyncPHP\Doorman\Rule\InMemoryRule'
    properties:
      Processes: 1
      MinimumProcessorUsage: 0
      MaximumProcessorUsage: 100

  DoormanRunner:
    class: Symbiote\QueuedJobs\Tasks\Engines\DoormanRunner
    properties:
      DefaultRules:
        - '%$DefaultRule'

  Symbiote\QueuedJobs\Services\QueuedJobService:
    properties:
      queueRunner: %$DoormanRunner
micschk commented 4 years ago

Could this be related to #288/#287?

mfendeksilverstripe commented 4 years ago

It seems so. The problem with the overriding via yaml is that you can only override array config which has named keys. This change adds a key to the default rule so it could be overridden. Additionally, null is allowed to be set as a rule to cover the case where you want to disable an existing rule.