Thanks to visit codestin.com
Credit goes to github.com

Skip to content

add DI container support - #109

Merged
LordSimal merged 2 commits into
masterfrom
di-support
Nov 28, 2022
Merged

LordSimal merged 2 commits into
masterfrom
di-support

Conversation

@LordSimal

Copy link
Copy Markdown
Member

This PR adds DI container support to tasks.

To do this you have to add the

use \Cake\Queue\Queue\ServicesTrait;

to your task.

With that you have access to the

$service = $this->getService(TestService::class);

method from which you can retrieve objects present inside the DI container.

Its basically the same structure/behavior as its currently available in dereuromark/cakephp-queue#327

@othercorey

Copy link
Copy Markdown
Contributor

Wouldn't DI support inject the services into the task through the constructor?

@LordSimal

Copy link
Copy Markdown
Member Author

I'd have to look into that if we want to build it that way.

@ndm2

ndm2 commented Nov 26, 2022

Copy link
Copy Markdown
Contributor

I haven't used the Queue plugin yet, but generally, if DI support is being expanded, I'd like to see CakePHP favor injection wherever possible.

While having proper service location is nice, my worry would be that going down that route could make a switch/upgrade to injection harder in the future.

@LordSimal

Copy link
Copy Markdown
Member Author

I only used dereuromarks queue plugin till now and I am happy with how the DI services are being accessible via the trait method mentioned above.

But for the core plugins I can definitely see enforcing constructor injected services as a "rule".

@LordSimal

LordSimal commented Nov 26, 2022

Copy link
Copy Markdown
Member Author

This now changed to how we are handling service injection into commands.
So services are injectable via the jobs constructor and the definition needs to be present inside the services() method of the app/plugin to

  • add the job to the DI container and
  • add the service as a argument to the constructor

But I am not really sure if this can lead to weird results if the worker is running for a longer time of period and the same type of job is being pushed to the queue over and over...

@ndm2

ndm2 commented Nov 27, 2022

Copy link
Copy Markdown
Contributor

But I am not really sure if this can lead to weird results if the worker is running for a longer time of period and the same type of job is being pushed to the queue over and over...

Do you have some specific problem in mind?

@markstory

Copy link
Copy Markdown
Member

But I am not really sure if this can lead to weird results if the worker is running for a longer time of period and the same type of job is being pushed to the queue over and over...

Do you have some specific problem in mind?

One scenario would be services that maintain state and rely on the implicit end of request to 'cleanup' the possibility of shared state.

My position on this is that we should document that services used in workers are long lived and shouldn't retain state. At the end of the day application developers are responsible for using services in queue workers safely.

In the future if this becomes a pain point we can address it then and find a way to reset the container instances after each job is processed.

@markstory markstory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Nice work 👏 I can take care of adding docs for this once it has merged.

Comment thread src/Plugin.php
*/
public function services(ContainerInterface $container): void
{
$container->add(ContainerInterface::class, $container);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do this in CakePHP itself as well? This seems like an elegant solution for other framework/plugin abstractions to leverage the DI container.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, this would be a nice default 😄

@LordSimal

Copy link
Copy Markdown
Member Author

One scenario would be services that maintain state and rely on the implicit end of request to 'cleanup' the possibility of shared state.

Thinking once more about it: Doesn't the DI Container create new instances by default whenever you ask for a specific service? Only if someone defines it as a shared service inside the services() method it will then be a singleton and therefore have state for each job/message process run.

But other shared state could definitely mess up how users expect it work.

@markstory

Copy link
Copy Markdown
Member

Only if someone defines it as a shared service inside the services() method it will then be a singleton and therefore have state for each job/message process run.

Yes, someone will do it eventually 😄

@LordSimal
LordSimal merged commit ffa8cc8 into master Nov 28, 2022
@LordSimal
LordSimal deleted the di-support branch November 28, 2022 17:23
markstory added a commit that referenced this pull request Nov 29, 2022
@LordSimal LordSimal mentioned this pull request Jan 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants