Problem/Motivation

Can we get a followup to add some document about lazy services to core.api.php - specifically the section on defining services in @defgroup container Services and Dependency Injection Container. Thanks

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork drupal-2514582

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Fabianx’s picture

Issue tags: +Documentation
Wim Leers’s picture

Issue summary: View changes

One IS template is sufficient :P

jhodgdon’s picture

OK, what are they? Is there a drupal.org page explaining them?

Fabianx’s picture

This chat should help:

09:54 <Fabianx-screen> So the problem is:
09:54 <Fabianx-screen> Service A depends on Service B, which depends on C,D,E,F,G
09:55 <Fabianx-screen> However during normal operation Service A does not use Service B.
09:55 <p>  Why would A declare
09:55 <p> a dep on B if it doesn't use it?
09:55 <Fabianx-screen> because in some code paths it still uses it.
09:55 <Fabianx-screen> just not in the render code path.
09:55 <Fabianx-screen> "normal operation"
09:55 <Fabianx-screen> e.g. logging
09:56 <Fabianx-screen> you need it only for exception cases, but not injecting it would violate encapsulation policy.
09:56 <Fabianx-screen> So now suddenly the light service A depends on all the services of service B.
09:56 <Fabianx-screen> The trick?
09:56 <Fabianx-screen> Make Service B a proxy.
09:56 <Fabianx-screen> So lets say A) uses the log() method of service B.
09:57 <Fabianx-screen> Then the proxy implements:
09:57 <Fabianx-screen> function log() {
09:57 <Fabianx-screen>   $this->lazyLoadItself();
09:57 <Fabianx-screen>   $this->service->log(func_get_args());
09:57 <Fabianx-screen> }
09:57 <Fabianx-screen> very simplified.
09:57 <Fabianx-screen> And lazy load itself asks the container for the service.
09:58 <p> So rather than go through the overhead of constructing a service it won't use, it loads only when called
09:58 <Fabianx-screen> yes, exactly.
09:58 <Fabianx-screen> But does so 100% transparent to the service.
09:58 <p> And this was, presumably, a performance thing
09:58 <Fabianx-screen> So that not all services do not to implement.
09:59 <Fabianx-screen> public function log() { if (!isset($this>logger)) { $this->logger = $this->container->get('logger'); } $this->logger->log(...); }
09:59 <p> This makes a lot of sense
10:00 <Fabianx-screen> which would mean that all services would depend on the container, which would then end up being a super-object ...
10:00 <Fabianx-screen> yes, implemented for performance.
10:00 <Fabianx-screen> No other reason.
10:00 <Fabianx-screen> System can work 100% without proxies, just slower :)
10:00 <Fabianx-screen> I hope that helps :).
10:00 <p> And the lazy services are manually compiled, always?
10:01 <Fabianx-screen> Yes, however we created a script to do so.
10:01 <p> Gotcha.
10:01 <Fabianx-screen> It was done automatically at container build time, but that had several problems.
10:01 <p> What were those problems, out of curiosity?
10:01 <Fabianx-screen> for example modules that are not yet loaded when the container was loaded, yet we needed the interface of the modules ...
10:02 <Fabianx-screen> no autoloading, e.g. all proxies always loaded.
10:02 <Fabianx-screen> etc.

On a high level overview.

jhodgdon’s picture

OK, so far, so good.

So what would a developer need to know about these? How do you create a lazy-loaded service proxy?

Fabianx’s picture

A developer will need to add "lazy: true" to their service definition in [module].services.yml and then would call e.g.:

./core/scripts/generate-proxy.sh 'Drupal\Core\Batch\BatchStorage' core/lib/Drupal/Core

      ->addUsage('\'Drupal\Core\Batch\BatchStorage\' "core/lib/Drupal/Core"')
      ->addUsage('\'Drupal\block\BlockRepository\' "core/modules/block/src"')
      ->addUsage('\'Drupal\mymodule\MyClass\' "modules/contrib/mymodule/src"');

etc.

jhodgdon’s picture

Hm... Well this still isn't clear to me.

I do not see addUsage() in Core... and what is this generate-proxy.sh thing?

Fabianx’s picture

I was too lazy to type it all out:

./core/scripts/generate-proxy.sh 'Drupal\Core\Batch\BatchStorage' core/lib/Drupal/Core

will generate a proxy for the BatchStorage class.

./core/scripts/generate-proxy.sh 'Drupal\block\BlockRepository' core/modules/block/src

will generate a proxy for the BlockRepository class.

./core/scripts/generate-proxy.sh 'Drupal\mymodule\MyClass\' modules/contrib/mymodule/src

will generate a proxy for the custom MyClass class.

So it is always:

FullyQualifiedClassName Root-of-the-Namespace, e.g. for modules the 'src' directory.

jhodgdon’s picture

This script does not exist. I see generate-proxy-class.php so I guess that is what you mean? That PHP file is awful -- it has no usage docs at all and some of the in-code comments are totally wrong like the line that says it's generating a database dump. Is there some plan to fix it up?

Fabianx’s picture

#9 Yes, that script.

Sorry :/

There are usage docs to what the Application provided via addUsage(), I am not sure how to add more.

Yes, the database script copy might have slipped through.

However on the plus side if you forget to run the script ( mark any service with lazy: true in core/config.services.yml or in any modules module.services.yml) and rebuild the drupal cache (drush cr) you will get very clear instructions how to run the script.

jhodgdon’s picture

RE #10 - That generate-proxy.php file:

a) Has no @file block at the top

b) As far as I can see, has zero relevant/correct comments in it except the one line that says "// Bootstrap."

So. It really could use a @file block telling at least what it does and how to use it, and at least a fix to that comment that implies it is running a database dump command.

Let's make that part of this issue of "documenting lazy services"?

Anyway... Do you want to make a first pass at writing this documentation? I am still a bit at a loss. I was not able to run this script on my slightly outdated local test site to see what it would do, and I am pretty busy right now with other stuff so I do not have time to write it. I don't think it's a Novice issue... so if you want this to get done we will need to find someone to write up this documentation.

Fabianx’s picture

Title: Document lazy services » Document lazy services and fix script doxygen

#11: Sorry, busy with Criticals, too.

Would it be possible when you triage the queue, that you ping again in 2 weeks or so?

And I agree the doxygen of the script should be fixed in here.

jhodgdon’s picture

Maybe assign it to yourself so it doesn't fall underneath your issue queue? The unresolved Docs issue queue runs to about 9 pages of 50 issues right now. This will get lost -- in two weeks it will be buried with all the other issues that got reported and never acted upon. The only ones that get fixed are the ones that get marked Novice, and this one ... I don't think it can be. Sorry.

Mile23’s picture

Status: Active » Needs review
FileSize
632 bytes

This sort of thing is why we need core integration of symfony/console. :-)

jhodgdon’s picture

Status: Needs review » Needs work

Thanks! That is a good start at the @file block for the script. A few thoughts:

  1. +++ b/core/scripts/generate-proxy-class.php
    @@ -1,6 +1,16 @@
    + * For help, type this command:
    + * php core/scripts/generate-proxy-class.php -h generate-proxy-class
    

    Should probably say to do this from your Drupal root directory. And apparently also that you have to run it from an installed Drupal code base, because when I tried running this in my "commit stuff to Core" git repo (which is not connected to an installed site), I got an exception.

  2. +++ b/core/scripts/generate-proxy-class.php
    @@ -1,6 +1,16 @@
    + * @see Drupal\Core\Command\GenerateProxyClassCommand
    

    The namespace in this line needs to start with \

  3. Also... I went and looked at that class and there's basically no documentation there either. Should we add documenting that class to the scope of this issue?

    At a minimum, when the topic is written, both this file and that class should probably have @ingroup services in them.

Mile23’s picture

Status: Needs work » Needs review
FileSize
652 bytes
702 bytes

Yah, it was a patch to get the conversation rolling. I'm not sure if this script is useful only for generating lazy services, or whether it has other uses.

#15.1: Added 'from your installed Drupal root...' Also, getting an exception instead of a help screen would be a bug if we had the console integration in place.

#15.2,3: I included the @see because it's reasonably readable code that shows you what's going on. It's probably not the best documentation effort. I'll just remove it. Also there's no @defgroup services but there is a @defgroup container, so I've added that. I'm not sure if it goes in @file, or if it should have its own docblock.

Still need a how-to writeup in core.api.php.

jhodgdon’s picture

Status: Needs review » Needs work

Looks good! Setting back to Needs Work since the topic has not yet been written.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

sahil.goyal’s picture

tried with the latest patch as it not getting applied so, Rerolling the patch for the drupal version 9.4.x and attaching the Reroll_Diff along with that,

nod_’s picture

Version: 9.4.x-dev » 10.1.x-dev
Status: Needs work » Needs review
nod_’s picture

Patch applies to 10.1.x as well.

I'd RTBC but from #17: "Looks good! Setting back to Needs Work since the topic has not yet been written." I do not know what that means.

joachim’s picture

I filed a duplicate of this. On my issue I wrote that documentation should say:

- why a particular class needs to be proxied
- where the list of classes that get proxied is defined
- what triggers the proxy class generation -- is it something a human must do when these classes are changed, or is it automatic?

joachim’s picture

Status: Needs review » Needs work
joachim’s picture

Assigned: Unassigned » joachim

I'm reading the comments on this -- I'll try to write a docs topic based on them.

joachim’s picture

Assigned: joachim » Unassigned
Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Random failure appears to be random ckeditor5 one. So LGTM

Not sure what topic either? Unless this needs a help_topic template but that wasn't around 7 years ago.

joachim’s picture

> Looks good! Setting back to Needs Work since the topic has not yet been written.

I assume this means the topic I've added to core.api.php with a @defgroup -- that's a documentation topic.

  • catch committed e2158bf on 10.0.x
    Issue #2514582 by Mile23, joachim, sahil.goyal, jhodgdon, Fabianx,...
  • catch committed 85b4d86 on 10.1.x
    Issue #2514582 by Mile23, joachim, sahil.goyal, jhodgdon, Fabianx,...
  • catch committed 2132990 on 9.5.x
    Issue #2514582 by Mile23, joachim, sahil.goyal, jhodgdon, Fabianx,...
catch’s picture

Version: 10.1.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.1.x and cherry-picked back through 9.5.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.