-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Config] RFC - Simplify and redesign ResourceInterface #7176
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
Comments
This was referenced Feb 25, 2013
5 tasks
I like it 👍 |
@stof What do you think? This is an old issue and not entirely up to date, but maybe something worth discussing for 3.0? |
@stof What is the right way to change or deprecate an interface for 3.0? I don't see how this could be done with deprecation error messages. |
@mpdude I think adding the PHPDoc and a global trigger_error in the head of the file. |
This was referenced Sep 7, 2015
fabpot
added a commit
that referenced
this issue
Sep 25, 2015
…pdude) This PR was squashed before being merged into the 2.8 branch (closes #15738). Discussion ---------- Implement service-based Resource (cache) validation | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #7230, #15692, #7782 | License | MIT | Doc PR | symfony/symfony-docs#5136 ### Overview Currently, any metadata passed to `ConfigCache` (namely implementations of `ResourceInterface`) is serialized to disk. When the `ConfigCache` is validated, the metadata is unserialized and queried through `ResourceInterface::isFresh()` to determine whether the cache is fresh. That way, `ResourceInterface` implementations cannot interact with services, for example a database connection. This PR introduces the new concept of `ResourceCheckers`. Services implementing `ResourceCheckerInterface` can be tagged as `config_cache.resource_checker` with an optional priority. Clients that wish to use `ConfigCache` can then obtain an instance from the `config_cache_factory` service (which implements `ConfigCacheFactoryInterface`). The factory will take care of injecting resource checkers into the `ConfigCache` instance so that they can be used for cache validation. Checking cache metadata is easy for `ResourceCheckers`: * First, the `ResourceCheckerInterface::supports()` implementation is passed the metadata object in question. If the checker cannot handle the type of resource passed, `supports()` should return `false`. * Otherwise, the `ResourceCheckerInterface::isFresh()` method will be called and given the resource as well as the timestamp at which the cache was initialized. If that method returns `false`, the cache is considered stale. If it returns `true`, the resource is considered unchanged and will *not* be passed to any additional checkers. ### BC and migration path This PR does not (intend to) break BC but it comes with deprecations. The main reason is that `ResourceInterface` contains an `isFresh()` method that does not make sense in the general case of resources. Thus, `ResourceInterface::isFresh()` is marked as deprecated and should be removed in Symfony 3.0. Resource implementations that can (or wish to) be validated in that simple manner can implement the `SelfCheckingResourceInterface` sub-interface that still contains (and will keep) the `isFresh()` method. The change should be as simple as changing the `extends` list. Apart from that, `ResourceInterface` will be kept as the base interface for resource implementations. It is used in several `@api` interfaces and thus cannot easily be substituted. For the Symfony 2.x series, a `BCResourceInterfaceChecker` will be kept that performs validation through `ResourceInterface::isFresh()` but will trigger a deprecation warning. The remedy is to either implement a custom ResourceChecker with a priority higher than -1000; or to switch to the aforementioned `SelfCheckingResourceInterface` which is used at a priority of -990 (without deprecation warning). The `ConfigCache` and `ConfigCacheFactory` classes can be used as previously but do not feature checker-based cache validation. ### Outlook and closing remarks: This PR supersedes #7230, #15692 and works at least in parts towards the goal of #7176. The `ResourceCheckerInterface`, `...ConfigCache` and `...ConfigCacheFactory` no longer need to be aware of the `debug` flag. The different validation rules applied previously are now just a matter of `ResourceChecker` configuration (i. e. "no checkers" in `prod`). It might be possible to remove the `debug` flag from Symfony's `Router` and/or `Translator` classes in the future as well because it was only passed on to the `ConfigCache` there. Commits ------- 20d3722 Implement service-based Resource (cache) validation
fabpot
added a commit
that referenced
this issue
Sep 26, 2015
This PR was merged into the 2.8 branch. Discussion ---------- Deprecate ResourceInterface::getResource() | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | n/a The return value of this method does not make sense if you do not exactly know about the type of resource at hand. For example, it may be [an array](https://github.com/symfony/symfony/blob/b49fa129bdb3c0aa970a006b16dd1ca63a9d7ebd/src/Symfony/Component/HttpKernel/Config/EnvParametersResource.php#L57) or a [file path](https://github.com/symfony/symfony/blob/87800ae47e64429f2544b798575d1cc1d4e5464a/src/Symfony/Component/Config/Resource/FileResource.php#L51). As all usages of getResource() within Symfony are in tests of particular Resource implementations anyway, deprecating and later removing this method helps us with simplifying the ResourceInterface (#7176). Commits ------- 87c0c7d Deprecate ResourceInterface::getResource()
symfony-splitter
pushed a commit
to symfony/config
that referenced
this issue
Sep 26, 2015
The return value of this method does not make sense if you do not exactly know about the type of resource at hand. For example, it may be [an array](https://github.com/symfony/symfony/blob/b49fa129bdb3c0aa970a006b16dd1ca63a9d7ebd/src/Symfony/Component/HttpKernel/Config/EnvParametersResource.php#L57) or a [file path](https://github.com/symfony/symfony/blob/87800ae47e64429f2544b798575d1cc1d4e5464a/src/Symfony/Component/Config/Resource/FileResource.php#L51). As all usages of getResource() within Symfony are in tests of particular Resource implementations anyway, deprecating and later removing this interface helps us with simplifying the ResourceInterface (symfony/symfony#7176).
symfony-splitter
pushed a commit
to symfony/config
that referenced
this issue
Feb 23, 2016
The return value of this method does not make sense if you do not exactly know about the type of resource at hand. For example, it may be [an array](https://github.com/symfony/symfony/blob/b49fa129bdb3c0aa970a006b16dd1ca63a9d7ebd/src/Symfony/Component/HttpKernel/Config/EnvParametersResource.php#L57) or a [file path](https://github.com/symfony/symfony/blob/87800ae47e64429f2544b798575d1cc1d4e5464a/src/Symfony/Component/Config/Resource/FileResource.php#L51). As all usages of getResource() within Symfony are in tests of particular Resource implementations anyway, deprecating and later removing this interface helps us with simplifying the ResourceInterface (symfony/symfony#7176).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently, Config/ResourceInterface and its implementations serve a single purpose - that is, checking whether data from a ConfigCache is still valid. For that, the cache is associated with a set of Resources which can later be checked for freshness. ConfigCache seems to be the only client of ResourceInterface right now.
The problem with the interface is that it somewhat assumes that resources are filesystem objects. Just as Loaders (Config/Loader/LoaderInterface) can load about anything, the same should be true for Resources.
For example, it is no problem to have a loader pull some information (think of translations) from a database. At a later time, you might need to check if the generated message catalogue is still up to date.
Implementing ResourceInterface in this case is difficult - __toString() and getResource() hardly make sense for "translations from a database", and at least to getResource() is the Loader's job. Anyway, both methods are not used by ConfigCache as the current sole client.
Freshness check based on timestamp
Checking isFresh($timestamp) - which means "is the Resource still the same as it was at $timestamp" - might also be implemented differently for the said database.
The $timestamp need not be a timestamp but just an opaque identifier (think ETag). Even more, as Resource implementations being serialized carry resource type-specific data anyway (a filename, for example), the entire way of validating them should be encapsulated in the Resource. That is, a Resource could upon creation get or keep what it needs for validation.
For example, a FileResource would grab the mtime() of the underlying file, keep it along with the filename (in its serialized form) and later on (when unserialized) check the mtime() again, comparing the two values.
A more simple, self-validating Resource interface
All this would lead to a ResourceInterface like
plus the requirement the implementors are (un)serializable without side effects.
Resource checks using services
I also made a suggestion how Resource validation could be shifted from the Resource implementation to some kind of "voter" or "checker" class which allows for using services (a database connection, a loader implementation) during the check which is not possible if the check has to be within the unserialized resource.
That would even leave Resource as a marker interface and have the "voter" implement a single "hasChanged(Resource $r)" method.
To sum up
I think simplifying the ResourceInterface would be a good thing to do because
Shifting the freshness check from Resource implementations to some kind of "voter"/"checker" additionally makes it possible to use services for validation, being a solution for at least one issue.
Opinions please. Will do the work if others agree :-).
Update: The current WIP is #7230.
The text was updated successfully, but these errors were encountered: