Skip to content

[Runtime] Init Runtime component #15081

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

Merged
merged 5 commits into from
Apr 7, 2021
Merged

[Runtime] Init Runtime component #15081

merged 5 commits into from
Apr 7, 2021

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Mar 9, 2021

This is documentation for symfony/symfony#38465

The docs is focus on "how to use" instead of "how it works". I will add a "creating your own Runtime" which will include "how it works".

As you may notice. I use two concepts: "the callback" and "the application". The fact that "the application" can be a callback and will be wrapped in callbacks is irrelevant here. I found it much easier to understand this way.

@wouterj
Copy link
Member

wouterj commented Mar 9, 2021

Hi @Nyholm. Thanks for your enthusiasm regarding this new component. However, we're working hard on removing standalone component documentation...

I think there are topics that are relevant in the framework-usage context:

  • How to modify the bootstrap
  • How does the framework boot itself (maybe as a configuration/, setup/ or introduction/ subguide)
  • ...

And we surely also need to somehow document its standalone usage, but I'm not sure if we should add new articles to the components/ section.

Before you continue here, let's discuss with the @symfony/team-symfony-docs how to document this new component.

@Nyholm
Copy link
Member Author

Nyholm commented Mar 9, 2021

we're working hard on removing standalone component documentation...

Oh, And here I am adding new pages =)

I started this work by adding a ./runtime.rst but I did find much to write about it. This component is a bit different from others. It is really not part of "the framework".

I'll wait for some opinions and guidance.

fabpot added a commit to symfony/symfony that referenced this pull request Mar 10, 2021
…m global state (nicolas-grekas)

This PR was merged into the 5.3-dev branch.

Discussion
----------

[Runtime] a new component to decouple applications from global state

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | symfony/symfony-docs#15081

Follow up of #36652, see discussion there.

What if we could decouple the bootstrapping logic of our apps from any global state?

This PR makes it possible via a new proposed `symfony/runtime` component.

The immediate benefit this provides is easier maintenance of Symfony apps: code that is currently shipped by recipes will be able to move to `vendor/`. Read the previous sentence twice, this is big :)
Check the following PR to see how far this goes: symfony/recipes#787

The longer-term benefit is being able to run the exact same app under several runtimes: PHP-FPM, CLI, but also PHP-PM and similar. Thanks to the proposed interface, this benefit could span to any PHP apps; not only to apps using the Symfony HttpKernel/HttpFoundation components. This part could be moved to `symfony/contracts` in the future.

Performance-wise, I measured no significant difference with the current way of running apps.

RuntimeInterface
----------------

The core of this component is the `RuntimeInterface` which describes a high-order
runtime logic.

It is designed to be totally generic and able to run any application outside of
the global state in 6 steps:

 1. the main entry point returns a callable that wraps the application;
 2. this callable is passed to `RuntimeInterface::getResolver()`, which returns a
    `ResolverInterface`; this resolver returns an array with the (potentially
    decorated) callable at index 0, and all its resolved arguments at index 1;
 3. the callable is invoked with its arguments; it returns an object that
    represents the application;
 4. that object is passed to `RuntimeInterface::getRunner()`, which returns a
    `RunnerInterface`: an instance that knows how to "run" the object;
 5. that instance is `run()` and returns the exit status code as `int`;
 6. the PHP engine is exited with this status code.

This process is extremely flexible as it allows implementations of
`RuntimeInterface` to hook into any critical steps.

Autoloading
-----------

This package registers itself as a Composer plugin to generate a
`vendor/autoload_runtime.php` file. This file shall be required instead of the
usual `vendor/autoload.php` in front-controllers that leverage this component
and return a callable.

Before requiring the `vendor/autoload_runtime.php` file, set the
`$_SERVER['APP_RUNTIME']` variable to a class that implements `RuntimeInterface`
and that should be used to run the returned callable.

Alternatively, the class of the runtime can be defined in the `extra.runtime.class`
entry of the `composer.json` file.

A `SymfonyRuntime` is used by default. It knows the conventions to run
Symfony and native PHP applications.

Examples
--------

This `public/index.php` is a "Hello World" that handles a "name" query parameter:
```php
<?php

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $request, array $context): void {
    // $request holds keys "query", "body", "files" and "session",
    // which map to $_GET, $_POST, $_FILES and &$_SESSION respectively

    // $context maps to $_SERVER

    $name = $request['query']['name'] ?? 'World';
    $time = $context['REQUEST_TIME'];

    echo sprintf('Hello %s, the current Unix timestamp is %s.', $name, $time);
};
```

This `bin/console.php` is a single-command "Hello World" application
(run `composer require symfony/console` before launching it):
```php
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (Command $command) {
    $command->addArgument('name', null, 'Who should I greet?', 'World');

    return $command->setCode(function (InputInterface $input, OutputInterface $output) {
        $name = $input->getArgument('name');
        $output->writeln(sprintf('Hello <comment>%s</>', $name));
    });
};
```

The `SymfonyRuntime` can resolve and handle many types related to the
`symfony/http-foundation` and `symfony/console` components.
Check its source code for more information.

Commits
-------

61b32ab [Runtime] a new component to decouple applications from global state
@mnapoli
Copy link
Contributor

mnapoli commented Mar 10, 2021

As I was curious about the runtime component, I saw your comment @wouterj:

we're working hard on removing standalone component documentation...

What will happen with the documentation of components like Filesystem, Process, Console, etc.? Will they only be documented for usage in the Symfony framework?

@wouterj
Copy link
Member

wouterj commented Mar 10, 2021

What will happen with the documentation of components like Filesystem, Process, Console, etc.? Will they only be documented for usage in the Symfony framework?

We're still a bit experimenting with this concept (which is why most components also still have their standalone docs). The main issue is twofold: lots of docs are duplicate & many people are confused (as they end up in component docs, while using a component within the framework). For some simpler components, we've moved the standalone example to the README file instead: https://github.com/symfony/routing#getting-started For HTTP client, we've used tabs to separate framework and component usage: https://symfony.com/doc/current/http_client.html

Process and Filesystem have very similar usage in framework and standalone (like HTTP client). Personally, I'm thinking they end up as a main guide that explains how to do the setup in the framework and their generic usage. Then the standalone set-up will be either an example in the README, or the tab-based examples of the HTTP client docs.

Components like Runtime are especially difficult, as their main goal is to be a generic package that can be reused..

@Nyholm
Copy link
Member Author

Nyholm commented Mar 11, 2021

I have added <?php on some code examples. It is the examples that is a pure PHP file. At the time of writing, I felt they should be treated differently than the normal "This code is part of a class"-examples.

Let me know if I should remove them.


Also, DOCtor-RST is red because:

components/runtime.rst ✘
   50: Please add "php" prefix before "bin/console"
   ->  // bin/console

Warning: ] Found "1" invalid file!                                              

Error: Please add "php" prefix before "bin/console"

That is a false positive, I refer the file, not the command.

fabpot added a commit to symfony/symfony that referenced this pull request Mar 17, 2021
This PR was merged into the 5.3-dev branch.

Discussion
----------

[Runtime] Remove "docs" from readme

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       |
| License       | MIT
| Doc PR        | symfony/symfony-docs#15081

Make the readme of the Runtime component link to the docs. This PR is blocked by the doc PR.

Commits
-------

6f4552f [Runtime] Remove "docs" from readme
@wouterj wouterj self-assigned this Mar 30, 2021
wouterj added a commit to Nyholm/symfony-docs that referenced this pull request Apr 5, 2021
wouterj added a commit to Nyholm/symfony-docs that referenced this pull request Apr 5, 2021
@wouterj
Copy link
Member

wouterj commented Apr 5, 2021

Thank you for the review @dbrumann!

As discussed with @Nyholm last week, I've pushed some rewordings directly to his fork (29ef3bf). Let me know what you think, I think it's ready for merge! :)

Copy link
Member Author

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Thank you very much for the help. Im happy with this PR.

@Nyholm
Copy link
Member Author

Nyholm commented Apr 7, 2021

I suggest merging this PR now. That will give some docs for the new component and it will allow others to help with small fixes.

We also need a github label for the component.

@OskarStark
Copy link
Contributor

I suggest merging this PR now. That will give some docs for the new component and it will allow others to help with small fixes.

I agree 👍

We also need a github label for the component.

friendly ping @fabpot @nicolas-grekas, not sure how and who is responsible for the labels

@wouterj
Copy link
Member

wouterj commented Apr 7, 2021

Label added

@wouterj wouterj added the Runtime label Apr 7, 2021
Nyholm and others added 5 commits April 7, 2021 14:48
Co-authored-by: Oskar Stark <oskarstark@googlemail.com>
Co-authored-by: Ondřej Frei <37588173+freiondrej@users.noreply.github.com>
Co-authored-by: Denis Brumann <dbrumann@gmail.com>
@wouterj wouterj merged commit bbe3709 into symfony:5.x Apr 7, 2021
@wouterj
Copy link
Member

wouterj commented Apr 7, 2021

Thank you @Nyholm for all your time invested in this document!

@OskarStark OskarStark added this to the 5.3 milestone Apr 7, 2021
@Nyholm Nyholm deleted the runtime branch April 7, 2021 13:03
@Nyholm
Copy link
Member Author

Nyholm commented Apr 7, 2021

Wohoo. Thank you for all the reviews and help

@Nyholm
Copy link
Member Author

Nyholm commented Apr 8, 2021

Sorry for being impatient.

When (or how often) is the documentation rebuilt? I was expected to see the content here: https://symfony.com/doc/current/runtime.html

@wouterj
Copy link
Member

wouterj commented Apr 8, 2021

@Nyholm you can find it here: https://symfony.com/doc/5.3/components/runtime.html (and the docs are rebuild every night)

@Nyholm
Copy link
Member Author

Nyholm commented Apr 8, 2021

Lovely. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants