- ๐ณ๐ฟNew Zealand jweowu
OK, so the general guidelines I'm hearing are:
1. If there is a large amount of data (or there are memory issues)
2. If you need a way to reset the cache (outside of tests)......use a Memory cache backend.
Else...
use properties on the service class.
Regarding (1), I don't think the amount of data should ever make a difference to the accessibility of the data.
Regarding (2), we cannot predict whether or not contrib or custom code might have a reason to inspect or manipulate or reset any given cache, so we shouldn't try -- it should simply be possible, as standard, and in a standard way.
I am therefore against the use of cache properties and/or plain
static
variables. A key benefit ofdrupal_static()
was having a standard API which enabled other code to interact with these caches as necessary. Regressing to an approach which hides that data away is a step backwards, as is the removal of a standard approach to working with such caches generally.drupal_static()
was simple, functional, and extremely standard across core and contrib code. I think that it should be replaced with something fitting that same description. - Status changed to Needs review
over 1 year ago 7:17am 24 May 2023 - last update
over 1 year ago Custom Commands Failed - ๐ฌ๐งUnited Kingdom catch
@jweowu yeah I don't think it's about the amount of data, but it should only be used for actual caches that will definitely get refreshed automatically.
- Status changed to Needs work
over 1 year ago 8:37pm 16 June 2023 The Needs Review Queue Bot โ tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide โ to find step-by-step guides for working with issues.
- ๐ฉ๐ชGermany donquixote
If the main concern is the reset problem, we can keep the object properties.
All we need is a mechanism for the reset, that does not pollute the public interface.The service with the runtime cache property subscribes to reset events, like this:
https://git.drupalcode.org/issue/drupal-3368812/-/commit/27b046020ac6f91...
(link might die)public function __construct( [..] private readonly ActiveModuleListInterface $activeModuleList, ResetDispatcherInterface $resetDispatcher, ) { // @todo Avoid double subscribe. $activeModuleList->subscribe($this->reset(...)); $resetDispatcher->subscribe(ModuleHandler::RESET_HOOKS, $this->reset(...)); $resetDispatcher->subscribe(ModuleHandler::EVENT_WRITE_CACHE, $this->writeCache(...)); [..] } public function reset(): void { $this->hookInfo = NULL; [..] }
There are different ways to implement this, which can coexist:
- A mutable data sources (e.g. a module list with ->addModule()) can have its own ->subscribe() method, and its own dispatch mechanism.
- A central dispatcher for these kinds of mini runtime events can keep a list of subscriber callbacks by id.
These cache properties are special, because they only need reset events after the object has been created.
E.g. symfony event dispatcher needs to "wake up" all the subscribed services. The runtime dispatcher only needs to message those services that have subscribed at runtime. This is why it is much easier to create and work with.The reset dispatcher does not need to send any data, it only has to "ping" the subscriber, which already has the data source as a dependency.
-
- ๐ง๐ชBelgium kristiaanvandeneynde Antwerp, Belgium
Following this issue, but my 2c regarding the factory:
- We have one for most other types of caches
- The documentation states we should use them (see below)
- MemoryCache is significantly faster than MemoryBackend, yet only the latter has a factory
Sidenotes:
- I realize why MemoryBackend (un)serializes data, but if we don't care about that then we will always prefer the faster sibling.
- If we don't add the cache.bin tag, the cache tags invalidator doesn't apply (unless we then wrap our cache in a chain)
From the in-code documentation:
/** * ... * A module can define a cache bin by defining a service in its * modulename.services.yml file as follows (substituting the desired name for * "nameofbin"): * @code * cache.nameofbin: * class: Drupal\Core\Cache\CacheBackendInterface * tags: * - { name: cache.bin } * factory: ['@cache_factory', 'get'] * arguments: [nameofbin] * @endcode * See the @link container Services topic @endlink for more on defining * services. * ... */
- ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
Looks like there's patches/MRs here so removing the [policy] prefix from the title.
- ๐ฉ๐ชGermany donquixote
Re myself in #40:
If the main concern is the reset problem, we can keep the object properties.
All we need is a mechanism for the reset, that does not pollute the public interface.We don't need to invent a new event mechanism. We can use the regular Drupal/symfony event dispatcher we use elsewhere, just use
->addListener()
instead of the usual subscription mechanism.
We only need to subscribe a service that is already instantiated.public function __construct( EventDispatcherInterface $dispatcher, ) { $dispatcher->addListener(self::EVENT_ID, $this->reset(...)); }