Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295783

Replace lazy service proxy generation with service closures

$
0
0

Problem/Motivation

As discussed in #3228623: DX: Creating lazy services is too difficult/obscure/bespoke/brittle the DX for our current lazy service proxies is poor. We tried using symfony lazy services in #3396928: Deprecate Drupal ProxyBuilder in favor of Symfony lazy services however that was not possible due to:

Sadly SF uses eval for the proxy classes which at least I can't see working with our serialized container solution

However we can now use service closures to lazy-load services which are supported by our serialized container.

Steps to reproduce

Proposed resolution

Replacy services tagged 'lazy' with service closures.

Prefer using autowiring and the #[AutowireServiceClosure] attribute over the !service_closure yaml command where possible.

https://symfony.com/doc/current/service_container/autowiring.html#genera...

This requires changing the constructor signature and adding a new method to invoke the closure like so:

Before:

public function __construct(
  protected CronInterface $cron,
) {}

Service definition:

services:
  my_service:
    class: Foo\Bar
    arguments: ['@cron']

After:

public function __construct(
  protected \Closure $cronClosure,
) {}


protected function getCron(): CronInterface {
  return ($this->cronClosure)();
}

Service definition:

services:
  my_service:
    class: Foo\Bar
    arguments: [!service_closure '@cron']

Autowiring approach

Before:

public function __construct(
  protected CronInterface $cron,
) {}

Service definition:

services:
  my_service:
    class: Foo\Bar
    autowire: true

After:

public function __construct(
#[AutowireServiceClosure('cron')]
  protected \Closure $cronClosure,
) {}


protected function getCron(): CronInterface {
  return ($this->cronClosure)();
}

Service definition:

services:
  my_service:
    class: Foo\Bar
    autowire: true

Remaining tasks

Current proxies under core/lib/Drupal/Core/ProxyClass:

├── Batch
│   └── BatchStorage.php
├── Config
│   └── ConfigInstaller.php
├── Cron.php
├── Extension
│   └── ModuleInstaller.php
├── File
│   └── MimeType
│       ├── ExtensionMimeTypeGuesser.php
│       └── MimeTypeGuesser.php
├── Lock
│   ├── DatabaseLockBackend.php
│   └── PersistentDatabaseLockBackend.php
├── Menu
│   └── MenuActiveTrail.php
├── PageCache
│   └── ChainResponsePolicy.php
├── ParamConverter
│   ├── AdminPathConfigEntityConverter.php
│   └── MenuLinkPluginConverter.php
├── Render
│   └── BareHtmlPageRenderer.php
└── Routing
    ├── MatcherDumper.php
    └── RouteBuilder.php

Proxies in core modules:

core/modules/language/src/ProxyClass/LanguageConverter.php
core/modules/node/src/ProxyClass/ParamConverter/NodePreviewConverter.php
core/modules/views_ui/src/ProxyClass/ParamConverter/ViewUIConverter.php

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet


Viewing all articles
Browse latest Browse all 295783


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>