Skip to content

Commit

Permalink
Merge branch '6.1' into 6.2
Browse files Browse the repository at this point in the history
* 6.1:
  Update ci.yaml
  Add documentation of Supervisor BACKOFF strategy
  Messenger process managers
  Updated SymfonyCloud link
  Proper line numbers on Doctrine Persisting example
  Changing `monolog.logger` to `logger`
  Remove obsolete warning
  • Loading branch information
javiereguiluz committed Sep 8, 2022
2 parents 1cbe327 + 5404ee4 commit 9f55837
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 26 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ on:
branches-ignore:
- 'github-comments'

permissions:
contents: read

jobs:
symfony-docs-builder-build:
name: Build (symfony-tools/docs-builder)
Expand Down
7 changes: 0 additions & 7 deletions components/config/resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@
Loading Resources
=================

.. caution::

The ``IniFileLoader`` parses the file contents using the
:phpfunction:`parse_ini_file` function. Therefore, you can only set
parameters to string values. To set parameters to other data types
(e.g. boolean, integer, etc), the other loaders are recommended.

Loaders populate the application's configuration from different sources
like YAML files. The Config component defines the interface for such
loaders. The :doc:`Dependency Injection </components/dependency_injection>`
Expand Down
2 changes: 1 addition & 1 deletion configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1115,4 +1115,4 @@ And all the other topics related to configuration:
.. _`Learn the XML syntax`: https://en.wikipedia.org/wiki/XML
.. _`environment variables`: https://en.wikipedia.org/wiki/Environment_variable
.. _`symbolic links`: https://en.wikipedia.org/wiki/Symbolic_link
.. _`utilities to manage env vars`: https://symfony.com/doc/master/cloud/cookbooks/env.html
.. _`utilities to manage env vars`: https://symfony.com/doc/current/cloud/env.html
10 changes: 5 additions & 5 deletions doctrine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -394,21 +394,21 @@ Take a look at the previous example in more detail:

.. _doctrine-entity-manager:

* **line 14** The ``ManagerRegistry $doctrine`` argument tells Symfony to
* **line 13** The ``ManagerRegistry $doctrine`` argument tells Symfony to
:ref:`inject the Doctrine service <services-constructor-injection>` into the
controller method.

* **line 16** The ``$doctrine->getManager()`` method gets Doctrine's
* **line 15** The ``$doctrine->getManager()`` method gets Doctrine's
*entity manager* object, which is the most important object in Doctrine. It's
responsible for saving objects to, and fetching objects from, the database.

* **lines 18-21** In this section, you instantiate and work with the ``$product``
* **lines 17-20** In this section, you instantiate and work with the ``$product``
object like any other normal PHP object.

* **line 24** The ``persist($product)`` call tells Doctrine to "manage" the
* **line 23** The ``persist($product)`` call tells Doctrine to "manage" the
``$product`` object. This does **not** cause a query to be made to the database.

* **line 27** When the ``flush()`` method is called, Doctrine looks through
* **line 26** When the ``flush()`` method is called, Doctrine looks through
all of the objects that it's managing to see if they need to be persisted
to the database. In this example, the ``$product`` object's data doesn't
exist in the database, so the entity manager executes an ``INSERT`` query,
Expand Down
118 changes: 112 additions & 6 deletions messenger.rst
Original file line number Diff line number Diff line change
Expand Up @@ -486,23 +486,30 @@ Deploying to Production

On production, there are a few important things to think about:

**Use Supervisor to keep your worker(s) running**
**Use a Process Manager like Supervisor or systemd to keep your worker(s) running**
You'll want one or more "workers" running at all times. To do that, use a
process control system like :ref:`Supervisor <messenger-supervisor>`.
process control system like :ref:`Supervisor <messenger-supervisor>`
or :ref:`systemd <messenger-systemd>`.

**Don't Let Workers Run Forever**
Some services (like Doctrine's ``EntityManager``) will consume more memory
over time. So, instead of allowing your worker to run forever, use a flag
like ``messenger:consume --limit=10`` to tell your worker to only handle 10
messages before exiting (then Supervisor will create a new process). There
messages before exiting (then the process manager will create a new process). There
are also other options like ``--memory-limit=128M`` and ``--time-limit=3600``.

**Stopping Workers That Encounter Errors**
If a worker dependency like your database server is down, or timeout is reached,
you can try to add :ref:`reconnect logic <middleware-doctrine>`, or just quit
the worker if it receives too many errors with the ``--failure-limit`` option of
the ``messenger:consume`` command.

**Restart Workers on Deploy**
Each time you deploy, you'll need to restart all your worker processes so
that they see the newly deployed code. To do this, run ``messenger:stop-workers``
on deployment. This will signal to each worker that it should finish the message
it's currently handling and should shut down gracefully. Then, Supervisor will create
new worker processes. The command uses the :ref:`app <cache-configuration-with-frameworkbundle>`
it's currently handling and should shut down gracefully. Then, the process manager
will create new worker processes. The command uses the :ref:`app <cache-configuration-with-frameworkbundle>`
cache internally - so make sure this is configured to use an adapter you like.

**Use the Same Cache Between Deploys**
Expand Down Expand Up @@ -665,11 +672,25 @@ times:
startsecs=0
autostart=true
autorestart=true
startretries=10
process_name=%(program_name)s_%(process_num)02d
Change the ``async`` argument to use the name of your transport (or transports)
and ``user`` to the Unix user on your server.

.. caution::

During a deployment, something might be unavailable (e.g. the
database) causing the consumer to fail to start. In this situation,
Supervisor will try ``startretries`` number of times to restart the
command. Make sure to change this setting to avoid getting the command
in a FATAL state, which will never restart again.

Each restart, Supervisor increases the delay by 1 second. For instance, if
the value is ``10``, it will wait 1 sec, 2 sec, 3 sec, etc. This gives the
service a total of 55 seconds to become available again. Increase the
``startretries`` setting to cover the maximum expected downtime.

If you use the Redis Transport, note that each worker needs a unique consumer
name to avoid the same message being handled by multiple workers. One way to
achieve this is to set an environment variable in the Supervisor configuration
Expand All @@ -692,7 +713,7 @@ Next, tell Supervisor to read your config and start your workers:
See the `Supervisor docs`_ for more details.

Graceful Shutdown
~~~~~~~~~~~~~~~~~
.................

If you install the `PCNTL`_ PHP extension in your project, workers will handle
the ``SIGTERM`` POSIX signal to finish processing their current message before
Expand All @@ -708,6 +729,88 @@ of the desired grace period in seconds) in order to perform a graceful shutdown:
[program:x]
stopwaitsecs=20
.. _messenger-systemd:

Systemd Configuration
~~~~~~~~~~~~~~~~~~~~~

While Supervisor is a great tool, it has the disadvantage that you need system
access to run it. Systemd has become the standard on most Linux distributions,
and has a good alternative called *user services*.

Systemd user service configuration files typically live in a ``~/.config/systemd/user``
directory. For example, you can create a new ``messenger-worker.service`` file. Or a
``messenger-worker@.service`` file if you want more instances running at the same time:

.. code-block:: ini
[Unit]
Description=Symfony messenger-consume %i
[Service]
ExecStart=php /path/to/your/app/bin/console messenger:consume async --time-limit=3600
Restart=always
RestartSec=30
[Install]
WantedBy=default.target
Now, tell systemd to enable and start one worker:

.. code-block:: terminal
$ systemctl --user enable messenger-worker@1.service
$ systemctl --user start messenger-worker@1.service
# to enable and start 20 workers
$ systemctl --user enable messenger-worker@{1..20}.service
$ systemctl --user start messenger-worker@{1..20}.service
If you change your service config file, you need to reload the daemon:

.. code-block:: terminal
$ systemctl --user daemon-reload
To restart all your consumers:

.. code-block:: terminal
$ systemctl --user restart messenger-consume@*.service
The systemd user instance is only started after the first login of the
particular user. Consumer often need to start on system boot instead.
Enable lingering on the user to activate that behavior:

.. code-block:: terminal
$ loginctl enable-linger <your-username>
Logs are managed by journald and can be worked with using the journalctl
command:

.. code-block:: terminal
# follow logs of consumer nr 11
$ journalctl -f --user-unit messenger-consume@11.service
# follow logs of all consumers
$ journalctl -f --user-unit messenger-consume@*
# follow all logs from your user services
$ journalctl -f _UID=$UID
See the `systemd docs`_ for more details.

.. note::

You either need elevated privileges for the ``journalctl`` command, or add
your user to the systemd-journal group:

.. code-block:: terminal
$ sudo usermod -a -G systemd-journal <your-username>
Stateless Worker
~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -2100,6 +2203,8 @@ middleware and *only* include your own:
If a middleware service is abstract, a different instance of the service will
be created per bus.

.. _middleware-doctrine:

Middleware for Doctrine
~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -2283,6 +2388,7 @@ Learn more
.. _`streams`: https://redis.io/topics/streams-intro
.. _`Supervisor docs`: http://supervisord.org/
.. _`PCNTL`: https://www.php.net/manual/book.pcntl.php
.. _`systemd docs`: https://www.freedesktop.org/wiki/Software/systemd/
.. _`SymfonyCasts' message serializer tutorial`: https://symfonycasts.com/screencast/messenger/transport-serializer
.. _`Long polling`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html
.. _`Visibility Timeout`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
Expand Down
19 changes: 12 additions & 7 deletions service_container.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,21 @@ What other services are available? Find out by running:
# this is just a *small* sample of the output...
Describes a logger instance.
Psr\Log\LoggerInterface (monolog.logger)
Autowirable Types
=================
Request stack that controls the lifecycle of requests.
Symfony\Component\HttpFoundation\RequestStack (request_stack)
The following classes & interfaces can be used as type-hints when autowiring:
RouterInterface is the interface that all Router classes must implement.
Symfony\Component\Routing\RouterInterface (router.default)
Describes a logger instance.
Psr\Log\LoggerInterface (logger)
[...]
Request stack that controls the lifecycle of requests.
Symfony\Component\HttpFoundation\RequestStack (request_stack)
RouterInterface is the interface that all Router classes must implement.
Symfony\Component\Routing\RouterInterface (router.default)
[...]
When you use these type-hints in your controller methods or inside your
:ref:`own services <service-container-creating-service>`, Symfony will automatically
Expand Down

0 comments on commit 9f55837

Please sign in to comment.