-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Runtime] make GenericRuntime ... generic #40513
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
dfbac81
to
489f53e
Compare
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.
This PR makes the GenericRuntime implementation able to auto-discover runtime implementations for specific types.
That is only true if the runtime is located in a class starting with Symfony\Runtime\
.. So if my acme/library
wants to create a "auto discoverable" runtime, then I need to define that namespace.
There is no clear way how to use GenericRuntime
as "main" and be able to pass options to the PsrRuntime
.
2698571
to
388c45d
Compare
Oh, I can pass the "PSR options" to the "GenericRuntime". Then on |
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.
Thank you. It took me a good 2 hours to test and review. Im happy with this PR after my last comment is resolved.
Well done 👍
388c45d
to
b1329d7
Compare
Correct, that's the convention. This effectively means that's we're globally reserving the Adding the namespace should be done in the "psr4": {
"Symfony\\Runtime\\Acme\\Lib\\": "src/Runtime/"
} |
0f7ff04
to
94d121d
Compare
(PR is ready, now tested) |
94d121d
to
1858158
Compare
1858158
to
33e371e
Compare
@@ -25,7 +25,7 @@ interface RuntimeInterface | |||
* | |||
* The callable itself should return an object that represents the application to pass to the getRunner() method. | |||
*/ | |||
public function getResolver(callable $callable): ResolverInterface; | |||
public function getResolver(callable $callable, \ReflectionFunction $reflector = null): ResolverInterface; |
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.
RuntimeInterface::getResolver()
now takes a second \ReflectionFunction $reflector = null
argument. This allows injecting the reflector to use to analyse the $callable
, providing both a small perf benefit when decorating, and allowing to decouple from the native implementation when needed.
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.
Could you show where you are using the second argument?
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'm not, this is just applying the DI principle. Actually, I played with the idea a bit a few times already. Some applications I won't submit for now:
- read a PHP8 attribute on the $callable to select the app-runtime;
- decorate
GenericRuntime::getResolver()
in a child class; - build the
ReflectionFunction
instance out of static data (aka caching).
All those use cases need to create a ReflectionFunction instance before calling the method. It would be a shame if all decorators in the chain would have to create this again and again. Not to mention the last use case, which needs an actual injection point.
Thank you Nicolas. |
This PR will allow #40436 to move to https://github.com/symfony/psr-http-message-bridge
For the record, it builds on a prototype I wrote almost one year ago at https://github.com/tchwork/bootstrapper.
This PR makes the
GenericRuntime
implementation able to auto-discover runtime implementations for specific types.It uses the autoloader for the discovery: when a closure-app requires or returns a type
Vendor\Foo
, it will use a convention and check if the classSymfony\Runtime\Vendor\FooRuntime
exists. If yes, it will use it to resolve the corresponding type. Such runtime classes have to extendGenericRuntime
so that they can use the protected API it provides. This requirement is aligned with the fact that the very convention proposed here is an implementation detail that works when using aGenericRuntime
as the main runtime (This behavior can be overridden by providing explicit entries in the newruntimes
option when booting theGenericRuntime
.)SymfonyRuntime
can be used as both the main runtime or a type-specific runtime: