-
-
Notifications
You must be signed in to change notification settings - Fork 327
WIP: Pluggable caching backends #647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
e6cb96d to
2cbcda2
Compare
|
Hi, thank you for the effort you put into that! Unfortunately I'm still not sure I understand the need behind that. The other thing is that this adds a lot of complexity and new code to maintain, and using an abstraction or PSR-6/16 adds overhead as well. I did some testing back then and using Doctrine Cache (which is fairly optimized) did add some overhead compared to a custom and simple cache implementation around APCu directly. |
| /** | ||
| * Returns the DI definition for the entry name. | ||
| * | ||
| * @param string $name The name of the definition to get |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big fan of adding obvious annotations. The type is already enforced, and the explanation for a method "getDefinition" with the parameter "name" is also pretty obvious: You get the definition for the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if there is a docblock, it should be complete, shouldn't it? I'm all for dropping the comment after $name though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My personal opinion: Docblocks should be as short as possible, and should not contain redundant information. Comments will start to contain wrong information in the long run, the less info they contain, the better.
Now, PHP-DI is a little bit inconsistent in this regard. If you look over some code, you'll find methods like this
PHP-DI/src/ContainerBuilder.php
Lines 220 to 226 in f16f27b
| * Enable or disable the use of autowiring to guess injections. | |
| * | |
| * Enabled by default. | |
| * | |
| * @return $this | |
| */ | |
| public function useAutowiring(bool $bool) : self |
PHP-DI/src/ContainerBuilder.php
Lines 272 to 278 in f16f27b
| * | |
| * @param bool $writeToFile If true, write the proxies to disk to improve performances | |
| * @param string|null $proxyDirectory Directory where to write the proxies | |
| * @throws InvalidArgumentException when writeToFile is set to true and the proxy directory is null | |
| * @return $this | |
| */ | |
| public function writeProxiesToFile(bool $writeToFile, string $proxyDirectory = null) : self |
I cannot define the code style for this project, @mnapoli is the project lead.
| * @var string|null | ||
| */ | ||
| private $sourceCache = false; | ||
| private $sourceCache; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably use another name for this property for defining the class name instead of recycling a property that already has a meaning, especially if it's type would change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming the property is a non-issue. What would you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cacheClass
|
The need for this is simple: If you run PHP in any long-running-process configuration (php-pm, amp, etc.) it's fully sufficient to simply cache in-memory. APCu is an overhead for us, we don't even run it in production. I also think that the introduced overhead of 2 method calls is negligable. In the end it's still only 1 object which does the same as Essentially it comes down to this: We have currently a copy of If you give your 👍 I will addthe missing tests for the new classes. |
- Establish interface `Cache\Cache` which represents any definition-cache - Move logic from `SourceCache` to both `Cache\AbstractCache` and `Cache\ApcuCache` - Deprecate `SourceCache` in favour of `Cache\ApcuCache` but still keep its functionality by extending the former. This is to keep backwards compatibility - Create a new simple cache-backend `ArrayCache` which just caches lookups in memory
Instead of tracking the caching status with a boolean, this commit changes `$sourceCache` to a nullable string. This allows to define different cache- backends. `::enableDefinitionCache(..)` not takes an optional parameter - optional to keep backwards compatibility - with the class-name of the definition cache to use. By default the `ApcuCache` is used which is identical to the deprecated, original `SourceCache`
2cbcda2 to
ae5adc6
Compare
|
@mnapoli Please consider merging something along these lines. The copied and modified version of ContainerBuilder we need to maintain in our source-tree broke prod builds after a composer upgrade again. I'm more than happy to implement the missing tests/refactorings if you greenlight this implementation. |
|
@bzikarsky sorry for the delay. The use case makes sense (not using APCu yet caching definitions in memory). I've been thinking about this and I wonder if it wouldn't make sense to always have the in-memory cache, even when using APCu. Indeed if a process gets the same definition twice it doesn't make sense to fetch it twice from APCu. That wouldn't mean a noticeable performance improvement but I think it might be a simpler architecture (no pluggable cache backend). What do you think? |
|
I agree on having an in-memory cache "by default". What I don't understand yet is why you insist to not move the "concern to cache" into a separate interface. From an architecture point-of-view smaller classes with a smaller footprint make sense in my opinion (and are also easier to test). Going with the proposed way would open the code up to all different kind of caching use-cases and with |
|
Well I was thinking of a simple key-value map of definitions that were already resolved but it seems I forgot that this exists already: Lines 151 to 154 in 2c7a3a6
Does that cover your use case? |
|
So... I know this is a very old PR, but priorities moved, but here we are again. I checked your proposal, but the issue is: While I am not sure: Maybe it's just possible to make I'd like to have your input:
|
|
I had a look, I think the I think 1. is the simplest solution. If you manage to implement it that would be best! |
|
Closed in favour of #709 |
Overview
This PR relates to #589 and refactors
SourceCacheinto pluggable caching-backends while keeping backwards compatibility.Current state
ContainerBuilderContents
Create an explicit, new class hierarchy for definition caching
Cache\Cachewhich represents any definition-cacheSourceCacheto bothCache\AbstractCacheandCache\ApcuCacheSourceCachein favour ofCache\ApcuCachebut stillkeep its functionality by extending the former. This is to keep
backwards compatibility
ArrayCachewhich just cacheslookups in memory
Integrate new Cache backend into ContainerBuilder
Instead of tracking the caching status with a boolean, this commit changes
$sourceCacheto a nullable string. This allows to define different cache-backends.
::enableDefinitionCache(..)not takes an optional parameter - optional tokeep backwards compatibility - with the class-name of the definition cache to
use. By default the
ApcuCacheis used which is identical to the deprecated,original
SourceCacheTests
TODO 😄
Future work
This functionality can be used to provide adapters to more general caching-backends, such as PSR-6 or PSR-16 compatible libraries.
In a major release
SourceCachecan be removed.