Skip to content

Added a new article about applications with multiple kernels #6840

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 11 commits into from
Dec 15, 2016

Conversation

javiereguiluz
Copy link
Member

@javiereguiluz javiereguiluz commented Aug 3, 2016

This fixes #997 (opened in January 2012 !!!).


  1. I don't know which is the best location for this article (probably not request/)

  2. When merging up, in the 2.8 branch the following must be added:

At the end of Step 2), add this:

In order to make this class available in the front controller, don't forget to
add it to the ``classmap`` configuration of the ``composer.json`` file:

.. code-block:: json

    {
        "autoload": {
            "psr-4": { "": "src/" },
            "classmap": ["app/AppKernel.php", "app/ApiKernel.php"]
        },
        ...
    }

At the end of the article, add this:

.. tip:

    Symfony 2.8 introduced a `new micro kernel`_ PHP trait that simplifies the
    creation of kernels. You can even define them in a single PHP file.

.. _`new micro kernel`: http://symfony.com/blog/new-in-symfony-2-8-symfony-as-a-microframework


// web/api.php
// ...
$kernel = new ApiKernel('prod', true);
Copy link
Member

@yceruto yceruto Aug 3, 2016

Choose a reason for hiding this comment

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

I guess the second parameter "debug" must be false here ?

Copy link
Member Author

Choose a reason for hiding this comment

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

You guessed right. Fixed. Thanks.

the ``app/config/api/`` directory.

The new configuration can be created from scratch when you load just a few
bundles, because it it will be very simple. Otherwise, duplicate the existing
Copy link
Member

Choose a reason for hiding this comment

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

typo "it it" ?

@yceruto
Copy link
Member

yceruto commented Aug 3, 2016

@javiereguiluz very nice article, thank!

@ogizanagi
Copy link
Contributor

ogizanagi commented Aug 3, 2016

I wonder if we shouldn't explain more the differences between kernel environments & using multiple kernels ? Because I know it can be confusing, especially for newcomers.

Especially as you state:

This is useful to execute the same application using a different configuration

But multiple kernels are not meant to execute the very same application with a different configuration. That's pretty much what kernel environments are for.

Different kernels are meant to execute different parts of a whole that can eventually be called "the application". It is true it doesn't often share much configuration, but what is important is that it's not the same part of the application at all. And thus, won't share the same components/bundles usage, nor sometimes some part of the business code, and above all not the same infrastructure stuff.

@javiereguiluz
Copy link
Member Author

@ogizanagi I completely agree with you. I've refactored the "use cases" section. Thanks!

only load the routes that match the parts of the application exposed to the
public. The second kernel would load the rest of the application and its
access would be protected by the web server;
* An application that uses a bundle which doesn't allow multiple instances could
Copy link
Contributor

@ogizanagi ogizanagi Aug 4, 2016

Choose a reason for hiding this comment

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

I'm not sure about this one.
It is presented as a solution to bundles registering a single service instead of allowing the creation of multiple instances through configuration. But creating new kernels has way too much impact to be considered for this use-case.
Once again, a kernel environment is probably more appropriate to define a different bundle configuration. But anyway, none of the 2 solutions would allow to make the different bundle configurations cohabit within the very same request. In my opinion, the sentence is misleading regarding this 😕.
The only solution for this use case is to not use the bundle/bundle configuration, and register services yourself.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK. I'm probably going to remove this use case. I added because the other day one person asked me if EasyAdmin supported defining two different backends in the same app. The bundle itself doesn't support that ... but with this multi-kernel trick, everything is easily solved.

Can anyone think of other use cases or do we just leave the first two proposed ones? Thanks.

Copy link
Contributor

@ogizanagi ogizanagi Aug 4, 2016

Choose a reason for hiding this comment

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

What about micro-services oriented apps ? You can split your services in multiple optimized modules, allowing to enable/disable a group of micro services on a server instance, by simply exposing or not a kernel instance.
It avoids dealing with multiple git repositories and allow to share code/configuration more easily.
However, it's very close to the mentioned API use-case, but with more advanced partitioning.

Copy link
Member Author

@javiereguiluz javiereguiluz Aug 4, 2016

Choose a reason for hiding this comment

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

That's nice! I've added that use case. Thanks.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe the most common use case is the front-end/back-end sceneries, a big e-commerce application, for example ?

@javiereguiluz
Copy link
Member Author

Lately I've been playing with multi-kernel apps, so I've just added a section which may be important: running commands using different kernels. I think this is ready for the final review. Thanks!


// web/api.php
// ...
$kernel = new ApiKernel('prod', false);
Copy link
Member

Choose a reason for hiding this comment

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

if you don't put a require call to load the file defining it, you already need to show the update of the autoload config

@@ -0,0 +1,183 @@
.. index::
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this should be in the configuration/ directory?


Creating a new kernel in a Symfony application is a three-step process:

1. Create a new front controller to load the new kernel;
Copy link
Member

Choose a reason for hiding this comment

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

There is another way to do this (which is done on a BIG Symfony site I know of): keeping app.php and app_dev.php and using some URL matching to load different kernels. For example, if the URL starts with /admin, then load the AdminKernel, else AppKernel. I think it's worth mentioning both. So, what about:

A) Making step (1) actually step (3) (I think creating the kernel and hooking up the configuration makes sense to have first, then finally show how you can instantiate the now-created kernel)

B) Rename this step to Step 3) Executing the kernel from a front controller

C) Mention the if statement approach above (it could be mentioned first or second).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Instead of creating the new front controller from scratch, it's recommended to
duplicate the existing ones. For example, create ``web/api_dev.php`` from
Copy link
Member

Choose a reason for hiding this comment

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

.> ... from scratch, it's easier to duplicate the existing ones

(it just sounds a bit more relaxed)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Now you need to define the ``ApiKernel`` class used by the new front controller.
The recommendation again is to duplicate the existing ``app/AppKernel.php`` file
Copy link
Member

Choose a reason for hiding this comment

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

The easiest way to do this is by duplicating the existing...

The recommendation again is to duplicate the existing ``app/AppKernel.php`` file
and make the needed changes.

In this example, the changes of the new ``ApiKernel`` would be to load less
Copy link
Member

Choose a reason for hiding this comment

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

In this example, the ApiKernel will load less bundles than AppKernel. Be sure to also change
the location of the cache, logs and config files so they don't collide with the files
from AppKernel

config files to not mess with the regular application::

// app/ApiKernel.php
<?php
Copy link
Member

Choose a reason for hiding this comment

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

We usually don't have the <?php. If you do want it for some specific reason, the filename should probably be moved inside of it, so that the comment is in PHP. But probably, we should just remove <?php

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Finally, define the configuration used by the application when it executes the
new API kernel. According to the previous code, this config must be defined in
Copy link
Member

Choose a reason for hiding this comment

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

Finally, define the configuration files that the new ApiKernel will load. According to the
above code, this config will live in the...

- { resource: ../config_dev.yml }

# override option values ...

Copy link
Member

Choose a reason for hiding this comment

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

Another option is to share some configuration files, especially if both kernels use some of the same bundles that you want configured in the same ways. I'm haven't done this enough to settle on the best organization for this... but we could at least mention it. Perhaps a app/config/shared.yml file where we show just a little bit of config and mention how you could import this from the config.yml file of both kernels.


Then, replace the ``AppKernel`` instantiation by your own kernel instantiation
(e.g. ``ApiKernel``) and now you can execute commands using the new kernel
(e.g. ``php bin/api cache:clear``) Now you can use execute commands using the new kernel
Copy link
Member

Choose a reason for hiding this comment

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

Extra:

Now you can use execute commands using the new kernel

and missing . at the end

--------------------------------------

If your application is very complex and you create several kernels, it's better
to store them on their own directories instead of messing with lots of files in
Copy link
Member

Choose a reason for hiding this comment

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

store them in their...

@weaverryan
Copy link
Member

This is really solid! 👍 from me if the changes are made.

Status: Needs Work

@weaverryan weaverryan merged commit bc3618d into symfony:2.7 Dec 15, 2016
weaverryan added a commit that referenced this pull request Dec 15, 2016
…rnels (javiereguiluz)

This PR was merged into the 2.7 branch.

Discussion
----------

Added a new article about applications with multiple kernels

This fixes #997 (opened in January 2012 !!!).

---

1) I don't know which is the best location for this article (probably not `request/`)

2) When merging up, in the 2.8 branch the following must be added:

At the end of `Step 2)`, add this:

``` rst
In order to make this class available in the front controller, don't forget to
add it to the ``classmap`` configuration of the ``composer.json`` file:

.. code-block:: json

    {
        "autoload": {
            "psr-4": { "": "src/" },
            "classmap": ["app/AppKernel.php", "app/ApiKernel.php"]
        },
        ...
    }
```

At the end of the article, add this:

``` rst
.. tip:

    Symfony 2.8 introduced a `new micro kernel`_ PHP trait that simplifies the
    creation of kernels. You can even define them in a single PHP file.

.. _`new micro kernel`: http://symfony.com/blog/new-in-symfony-2-8-symfony-as-a-microframework

```

Commits
-------

bc3618d Made a bunch of fixes recommended by Ryan
2613810 Added a note about rendering templates from different kernels
e403fd8 Added a new section about running commands under a different kernel
af4ff18 Added a new use case related to micro-services
2c5aeb1 Removed a use case
097a73d Reworded the use cases section
5c8ed87 Fixed typo
d45e1f4 Fixed an example code
a23d82d Fixed another syntax issue
21329ec Fixed some syntax issues
7cb2aa1 Added a new article about applications with multiple kernels
weaverryan added a commit that referenced this pull request Dec 15, 2016
@weaverryan
Copy link
Member

It's merged! Woohoo!

weaverryan added a commit that referenced this pull request Dec 15, 2016
* 2.7: (22 commits)
  [#6894] Adding link to Doctrine
  [#6857] Re-wording the section a bit
  [#6840] Adding note based on Stof's feedback
  Moving file - I think configuration is more appropriate
  Revert "Updated the contents for the new Symfony 3 dir structure"
  Updated the contents for the new Symfony 3 dir structure
  Remove "Symfony3 will use"
  Using lower case on "Form"
  Made a bunch of fixes recommended by Ryan
  Added a note about rendering templates from different kernels
  Added a new section about running commands under a different kernel
  Integrated improvement by javiereguiluz
  Explain what happens if `flush()` fails
  Update events.rst
  Added a new use case related to micro-services
  Removed a use case
  Reworded the use cases section
  Fixed typo
  Fixed an example code
  Fixed another syntax issue
  ...
weaverryan added a commit that referenced this pull request Dec 15, 2016
* 2.8: (22 commits)
  [#6894] Adding link to Doctrine
  [#6857] Re-wording the section a bit
  [#6840] Adding note based on Stof's feedback
  Moving file - I think configuration is more appropriate
  Revert "Updated the contents for the new Symfony 3 dir structure"
  Updated the contents for the new Symfony 3 dir structure
  Remove "Symfony3 will use"
  Using lower case on "Form"
  Made a bunch of fixes recommended by Ryan
  Added a note about rendering templates from different kernels
  Added a new section about running commands under a different kernel
  Integrated improvement by javiereguiluz
  Explain what happens if `flush()` fails
  Update events.rst
  Added a new use case related to micro-services
  Removed a use case
  Reworded the use cases section
  Fixed typo
  Fixed an example code
  Fixed another syntax issue
  ...
weaverryan added a commit that referenced this pull request Dec 15, 2016
* 3.1: (25 commits)
  [#6894] Adding link to Doctrine
  [#6857] Re-wording the section a bit
  [#6840] Adding note based on Stof's feedback
  Moving file - I think configuration is more appropriate
  Revert "Updated the contents for the new Symfony 3 dir structure"
  Updated the contents for the new Symfony 3 dir structure
  Remove "Symfony3 will use"
  Using lower case on "Form"
  Make lines shorter to comply with our soft limit of 80 chars per line
  Made a bunch of fixes recommended by Ryan
  Added a note about rendering templates from different kernels
  Fix comments
  [Serializer] Docs for the @MaxDepth annotation
  Added a new section about running commands under a different kernel
  Integrated improvement by javiereguiluz
  Explain what happens if `flush()` fails
  Update events.rst
  Added a new use case related to micro-services
  Removed a use case
  Reworded the use cases section
  ...
weaverryan added a commit that referenced this pull request Dec 15, 2016
* 3.2: (26 commits)
  [#6894] Adding link to Doctrine
  [#6857] Re-wording the section a bit
  [#6840] Adding note based on Stof's feedback
  Moving file - I think configuration is more appropriate
  Revert "Updated the contents for the new Symfony 3 dir structure"
  Updated the contents for the new Symfony 3 dir structure
  Remove "Symfony3 will use"
  Using lower case on "Form"
  Added a mention to sameSite cookie option
  Make lines shorter to comply with our soft limit of 80 chars per line
  Made a bunch of fixes recommended by Ryan
  Added a note about rendering templates from different kernels
  Fix comments
  [Serializer] Docs for the @MaxDepth annotation
  Added a new section about running commands under a different kernel
  Integrated improvement by javiereguiluz
  Explain what happens if `flush()` fails
  Update events.rst
  Added a new use case related to micro-services
  Removed a use case
  ...
@javiereguiluz javiereguiluz deleted the multiple_kernels branch May 24, 2018 16:04
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.

6 participants