Skip to content

Commit 2570023

Browse files
committed
Merge branch '5.4' into 6.0
* 5.4: 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
2 parents 5b6a783 + cc84d2a commit 2570023

File tree

6 files changed

+133
-26
lines changed

6 files changed

+133
-26
lines changed

.github/workflows/ci.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ on:
88
branches-ignore:
99
- 'github-comments'
1010

11+
permissions:
12+
contents: read
13+
1114
jobs:
1215
symfony-docs-builder-build:
1316
name: Build (symfony-tools/docs-builder)

components/config/resources.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
Loading Resources
55
=================
66

7-
.. caution::
8-
9-
The ``IniFileLoader`` parses the file contents using the
10-
:phpfunction:`parse_ini_file` function. Therefore, you can only set
11-
parameters to string values. To set parameters to other data types
12-
(e.g. boolean, integer, etc), the other loaders are recommended.
13-
147
Loaders populate the application's configuration from different sources
158
like YAML files. The Config component defines the interface for such
169
loaders. The :doc:`Dependency Injection </components/dependency_injection>`

configuration.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1130,4 +1130,4 @@ And all the other topics related to configuration:
11301130
.. _`Learn the XML syntax`: https://en.wikipedia.org/wiki/XML
11311131
.. _`environment variables`: https://en.wikipedia.org/wiki/Environment_variable
11321132
.. _`symbolic links`: https://en.wikipedia.org/wiki/Symbolic_link
1133-
.. _`utilities to manage env vars`: https://symfony.com/doc/master/cloud/cookbooks/env.html
1133+
.. _`utilities to manage env vars`: https://symfony.com/doc/current/cloud/env.html

doctrine.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,21 +394,21 @@ Take a look at the previous example in more detail:
394394

395395
.. _doctrine-entity-manager:
396396

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

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

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

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

411-
* **line 27** When the ``flush()`` method is called, Doctrine looks through
411+
* **line 26** When the ``flush()`` method is called, Doctrine looks through
412412
all of the objects that it's managing to see if they need to be persisted
413413
to the database. In this example, the ``$product`` object's data doesn't
414414
exist in the database, so the entity manager executes an ``INSERT`` query,

messenger.rst

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -476,23 +476,30 @@ Deploying to Production
476476

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

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

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

491+
**Stopping Workers That Encounter Errors**
492+
If a worker dependency like your database server is down, or timeout is reached,
493+
you can try to add :ref:`reconnect logic <middleware-doctrine>`, or just quit
494+
the worker if it receives too many errors with the ``--failure-limit`` option of
495+
the ``messenger:consume`` command.
496+
490497
**Restart Workers on Deploy**
491498
Each time you deploy, you'll need to restart all your worker processes so
492499
that they see the newly deployed code. To do this, run ``messenger:stop-workers``
493500
on deployment. This will signal to each worker that it should finish the message
494-
it's currently handling and should shut down gracefully. Then, Supervisor will create
495-
new worker processes. The command uses the :ref:`app <cache-configuration-with-frameworkbundle>`
501+
it's currently handling and should shut down gracefully. Then, the process manager
502+
will create new worker processes. The command uses the :ref:`app <cache-configuration-with-frameworkbundle>`
496503
cache internally - so make sure this is configured to use an adapter you like.
497504

498505
**Use the Same Cache Between Deploys**
@@ -655,11 +662,25 @@ times:
655662
startsecs=0
656663
autostart=true
657664
autorestart=true
665+
startretries=10
658666
process_name=%(program_name)s_%(process_num)02d
659667
660668
Change the ``async`` argument to use the name of your transport (or transports)
661669
and ``user`` to the Unix user on your server.
662670

671+
.. caution::
672+
673+
During a deployment, something might be unavailable (e.g. the
674+
database) causing the consumer to fail to start. In this situation,
675+
Supervisor will try ``startretries`` number of times to restart the
676+
command. Make sure to change this setting to avoid getting the command
677+
in a FATAL state, which will never restart again.
678+
679+
Each restart, Supervisor increases the delay by 1 second. For instance, if
680+
the value is ``10``, it will wait 1 sec, 2 sec, 3 sec, etc. This gives the
681+
service a total of 55 seconds to become available again. Increase the
682+
``startretries`` setting to cover the maximum expected downtime.
683+
663684
If you use the Redis Transport, note that each worker needs a unique consumer
664685
name to avoid the same message being handled by multiple workers. One way to
665686
achieve this is to set an environment variable in the Supervisor configuration
@@ -682,7 +703,7 @@ Next, tell Supervisor to read your config and start your workers:
682703
See the `Supervisor docs`_ for more details.
683704

684705
Graceful Shutdown
685-
~~~~~~~~~~~~~~~~~
706+
.................
686707

687708
If you install the `PCNTL`_ PHP extension in your project, workers will handle
688709
the ``SIGTERM`` POSIX signal to finish processing their current message before
@@ -698,6 +719,88 @@ of the desired grace period in seconds) in order to perform a graceful shutdown:
698719
[program:x]
699720
stopwaitsecs=20
700721
722+
.. _messenger-systemd:
723+
724+
Systemd Configuration
725+
~~~~~~~~~~~~~~~~~~~~~
726+
727+
While Supervisor is a great tool, it has the disadvantage that you need system
728+
access to run it. Systemd has become the standard on most Linux distributions,
729+
and has a good alternative called *user services*.
730+
731+
Systemd user service configuration files typically live in a ``~/.config/systemd/user``
732+
directory. For example, you can create a new ``messenger-worker.service`` file. Or a
733+
``messenger-worker@.service`` file if you want more instances running at the same time:
734+
735+
.. code-block:: ini
736+
737+
[Unit]
738+
Description=Symfony messenger-consume %i
739+
740+
[Service]
741+
ExecStart=php /path/to/your/app/bin/console messenger:consume async --time-limit=3600
742+
Restart=always
743+
RestartSec=30
744+
745+
[Install]
746+
WantedBy=default.target
747+
748+
Now, tell systemd to enable and start one worker:
749+
750+
.. code-block:: terminal
751+
752+
$ systemctl --user enable messenger-worker@1.service
753+
$ systemctl --user start messenger-worker@1.service
754+
755+
# to enable and start 20 workers
756+
$ systemctl --user enable messenger-worker@{1..20}.service
757+
$ systemctl --user start messenger-worker@{1..20}.service
758+
759+
If you change your service config file, you need to reload the daemon:
760+
761+
.. code-block:: terminal
762+
763+
$ systemctl --user daemon-reload
764+
765+
To restart all your consumers:
766+
767+
.. code-block:: terminal
768+
769+
$ systemctl --user restart messenger-consume@*.service
770+
771+
The systemd user instance is only started after the first login of the
772+
particular user. Consumer often need to start on system boot instead.
773+
Enable lingering on the user to activate that behavior:
774+
775+
.. code-block:: terminal
776+
777+
$ loginctl enable-linger <your-username>
778+
779+
Logs are managed by journald and can be worked with using the journalctl
780+
command:
781+
782+
.. code-block:: terminal
783+
784+
# follow logs of consumer nr 11
785+
$ journalctl -f --user-unit messenger-consume@11.service
786+
787+
# follow logs of all consumers
788+
$ journalctl -f --user-unit messenger-consume@*
789+
790+
# follow all logs from your user services
791+
$ journalctl -f _UID=$UID
792+
793+
See the `systemd docs`_ for more details.
794+
795+
.. note::
796+
797+
You either need elevated privileges for the ``journalctl`` command, or add
798+
your user to the systemd-journal group:
799+
800+
.. code-block:: terminal
801+
802+
$ sudo usermod -a -G systemd-journal <your-username>
803+
701804
Stateless Worker
702805
~~~~~~~~~~~~~~~~
703806

@@ -2026,6 +2129,8 @@ middleware and *only* include your own:
20262129
If a middleware service is abstract, a different instance of the service will
20272130
be created per bus.
20282131

2132+
.. _middleware-doctrine:
2133+
20292134
Middleware for Doctrine
20302135
~~~~~~~~~~~~~~~~~~~~~~~
20312136

@@ -2209,6 +2314,7 @@ Learn more
22092314
.. _`streams`: https://redis.io/topics/streams-intro
22102315
.. _`Supervisor docs`: http://supervisord.org/
22112316
.. _`PCNTL`: https://www.php.net/manual/book.pcntl.php
2317+
.. _`systemd docs`: https://www.freedesktop.org/wiki/Software/systemd/
22122318
.. _`SymfonyCasts' message serializer tutorial`: https://symfonycasts.com/screencast/messenger/transport-serializer
22132319
.. _`Long polling`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html
22142320
.. _`Visibility Timeout`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html

service_container.rst

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,21 @@ What other services are available? Find out by running:
5656
5757
# this is just a *small* sample of the output...
5858
59-
Describes a logger instance.
60-
Psr\Log\LoggerInterface (monolog.logger)
59+
Autowirable Types
60+
=================
6161
62-
Request stack that controls the lifecycle of requests.
63-
Symfony\Component\HttpFoundation\RequestStack (request_stack)
62+
The following classes & interfaces can be used as type-hints when autowiring:
6463
65-
RouterInterface is the interface that all Router classes must implement.
66-
Symfony\Component\Routing\RouterInterface (router.default)
64+
Describes a logger instance.
65+
Psr\Log\LoggerInterface (logger)
6766
68-
[...]
67+
Request stack that controls the lifecycle of requests.
68+
Symfony\Component\HttpFoundation\RequestStack (request_stack)
69+
70+
RouterInterface is the interface that all Router classes must implement.
71+
Symfony\Component\Routing\RouterInterface (router.default)
72+
73+
[...]
6974
7075
When you use these type-hints in your controller methods or inside your
7176
:ref:`own services <service-container-creating-service>`, Symfony will automatically

0 commit comments

Comments
 (0)