PHPackages                             baldinof/roadrunner-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. baldinof/roadrunner-bundle

ActiveSymfony-bundle[Queues &amp; Workers](/categories/queues)

baldinof/roadrunner-bundle
==========================

A RoadRunner worker as a Symfony Bundle

3.3.2(4mo ago)3061.3M—3.7%59[13 issues](https://github.com/Baldinof/roadrunner-bundle/issues)[7 PRs](https://github.com/Baldinof/roadrunner-bundle/pulls)1MITPHPPHP &gt;=8.1CI passing

Since Dec 10Pushed 4mo ago3 watchersCompare

[ Source](https://github.com/Baldinof/roadrunner-bundle)[ Packagist](https://packagist.org/packages/baldinof/roadrunner-bundle)[ GitHub Sponsors](https://github.com/Baldinof)[ RSS](/packages/baldinof-roadrunner-bundle/feed)WikiDiscussions 3.x Synced 1mo ago

READMEChangelog (10)Dependencies (28)Versions (56)Used By (1)

Roadrunner Bundle
=================

[](#roadrunner-bundle)

[RoadRunner](https://roadrunner.dev/) is a high-performance PHP application server, load-balancer, and process manager written in Golang.

This bundle provides a RoadRunner Worker integrated in Symfony, it's easily configurable and extendable.

Installation
------------

[](#installation)

Run the following command:

```
composer require baldinof/roadrunner-bundle

```

If you don't use Symfony Flex:

- register `Baldinof\RoadRunnerBundle\BaldinofRoadRunnerBundle` in your kernel
- copy default RoadRunner configuration files: `cp vendor/baldinof/roadrunner-bundle/.rr.* .`

Usage
-----

[](#usage)

- require the RoadRunner download utility: `composer require --dev spiral/roadrunner-cli`
- get the RoadRunner binary: `vendor/bin/rr get --location bin/`
- run RoadRunner with `bin/rr serve` or `bin/rr serve -c .rr.dev.yaml` (watch mode)
- visit your app at

Integrations
------------

[](#integrations)

Depending on installed bundle &amp; your configuration, this bundles add some integrations:

- **Sentry**: configure the request context (if the [`SentryBundle`](https://github.com/getsentry/sentry-symfony) is installed)
- **Sessions**: add the session cookie to the Symfony response (if `framework.sessions.enabled` config is `true`)
- **Doctrine Mongo Bundle**: clear opened managers after each requests (if [`DoctrineMongoDBBundle`](https://github.com/doctrine/DoctrineMongoDBBundle) is installed)
- **Doctrine ORM Bundle**: clear opened managers and check connection is still usable after each requests (if [`DoctrineBundle`](https://github.com/doctrine/DoctrineBundle) is installed)
- **Blackfire**: enable the probe when a profile is requested (if the [`blackfire`](https://blackfire.io/) extension is installed)
- **Xdebug**: allow Xdebug in trigger mode (if the [`xdebug`](https://xdebug.org/) extension is installed)

Even if it is not recommended, you can disable default integrations:

```
baldinof_road_runner:
  default_integrations: false
```

Middlewares
-----------

[](#middlewares)

You can use middlewares to manipulate request &amp; responses. Middlewares must implements [`Baldinof\RoadRunnerBundle\Http\MiddlewareInterface`](./src/Http/MiddlewareInterface.php).

Example configuration:

```
baldinof_road_runner:
    middlewares:
        - App\Middleware\YourMiddleware
```

Be aware that

- middlewares are run outside of Symfony `Kernel::handle()`
- the middleware stack is always resolved at worker start (can be a performance issue if your middleware initialization takes time)

Kernel reboots
--------------

[](#kernel-reboots)

The Symfony kernel and the dependency injection container are **preserved between requests**. If an exception is thrown during the request handling, the kernel is rebooted and a fresh container is used.

The goal is to prevent services to be in a non-recoverable state after an error.

To optimize your worker you can allow exceptions that does not put your app in an errored state:

```
# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: on_exception
      allowed_exceptions:
        - Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
        - Symfony\Component\Serializer\Exception\ExceptionInterface
        - App\Exception\YourDomainException
```

> If some of your services are stateful, you can implement `Symfony\Contracts\Service\ResetInterface` and your service will be resetted on each request.

If you are seeing issues and want to use a fresh container on each request you can use the `always` reboot strategy:

```
# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: always
```

If you are building long-running application and need to reboot it every XXX request to prevent memory leaks you can use `max_jobs` reboot strategy:

```
# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: max_jobs
      max_jobs: 1000 # maximum number of request
      max_jobs_dispersion: 0.2 # dispersion 20% used to prevent simultaneous reboot of all active workers (kernel will rebooted between 800 and 1000 requests)
```

If you want to reboot the worker when memory usage exceeds a certain threshold to prevent memory exhaustion you can use `memory` reboot strategy:

```
# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: memory
      memory_threshold_mb: 256 # memory threshold in megabytes (default: 128MB)
```

You can combine reboot strategies:

```
# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
    kernel_reboot:
      strategy: [on_exception, max_jobs, memory]
      allowed_exceptions:
        - Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
        - Symfony\Component\Serializer\Exception\ExceptionInterface
        - App\Exception\YourDomainException
      max_jobs: 1000
      max_jobs_dispersion: 0.2
      memory_threshold_mb: 256
```

Events
------

[](#events)

The following events are dispatched throughout the worker lifecycle:

- `Baldinof\RoadRunnerBundle\Event\WorkerStartEvent`: Dispatched right before the worker starts listening to requests.
- `Baldinof\RoadRunnerBundle\Event\WorkerStopEvent`: Dispatched right before the worker closes.
- `Baldinof\RoadRunnerBundle\Event\WorkerExceptionEvent`: Dispatched after encountering an uncaught exception during request handling.
- `Baldinof\RoadRunnerBundle\Event\WorkerKernelRebootedEvent`: Dispatched after the symfony kernel was rebooted (see Kernel reboots).

Development mode
----------------

[](#development-mode)

Copy the dev config file if it's not present: `cp vendor/baldinof/roadrunner-bundle/.rr.dev.yaml .`

Start RoadRunner with the dev config file:

```
bin/rr serve -c .rr.dev.yaml

```

Reference:

If you use the Symfony VarDumper, dumps will not be shown in the HTTP Response body. You can view dumps with `bin/console server:dump` or in the profiler.

Metrics
-------

[](#metrics)

Roadrunner can [collect application metrics](https://roadrunner.dev/docs/beep-beep-metrics), and expose a prometheus endpoint.

Example configuration:

```
# config/packages/baldinof_road_runner.yaml
baldinof_road_runner:
  metrics:
    enabled: true
    collect:
      user_login:
        type: counter
        help: "Number of logged in user"
```

And configure RoadRunner:

```
# .rr.yaml
rpc:
  listen: "tcp:127.0.0.1:6001"

metrics:
  address: "0.0.0.0:9180" # prometheus endpoint
```

Then simply inject `Spiral\RoadRunner\MetricsInterface` to record metrics:

```
class YouController
{
    public function index(MetricsInterface $metrics): Response
    {
        $metrics->add('user_login', 1);

        return new Response("...");
    }
}
```

gRPC
----

[](#grpc)

gRPC support was added by the roadrunner-grpc plugin for RoadRunner 2 ().

To configure Roadrunner for gRPC, refer to the configuration reference at . Basic configuration example:

```
server:
  command: "php public/index.php"
  env:
    APP_RUNTIME: Baldinof\RoadRunnerBundle\Runtime\Runtime

grpc:
  listen: "tcp://:9001"

  proto:
    - "calculator.proto"
```

Once you have generated your PHP files from proto files, you just have to implement the service interfaces. GRPC services are registered automatically. Example service:

```
