RoadRunner
  • 🟠General
    • What is RoadRunner?
    • Features
    • Quick Start
    • Installation
    • Configuration
    • Contributing
    • Upgrade and Compatibility
  • 👷PHP Worker
    • Worker
    • Workers pool
    • Developer mode
    • Code Coverage
    • Debugging
    • Environment
    • Manual workers scaling
    • Auto workers scaling
    • RPC
  • 🟢Customization
    • Building RR with a custom plugin
    • Integrating with Golang Apps
    • Writing a Middleware
    • Writing a Jobs Driver
    • Writing a Plugin
    • Events Bus
  • 🔌Plugins
    • Intro into Plugins
    • Centrifuge (WebSockets)
    • Service (Systemd)
    • Configuration
    • Server
    • Locks
    • gRPC
    • TCP
  • 🌐Community Plugins
    • Intro into Community Plugins
    • Circuit Breaker
    • SendRemoteFile
    • RFC 7234 Cache
  • 🔵App Server
    • Production Usage
    • RoadRunner with NGINX
    • RR as AWS Lambda
    • Docker Images
    • CLI Commands
    • Systemd
  • 🔐Key-Value
    • Intro into KV
    • Memcached
    • In-Memory
    • BoltDB
    • Redis
  • 📦Queues and Jobs
    • Intro into Jobs
    • Google Pub/Sub
    • Beanstalk
    • In-Memory
    • RabbitMQ
    • BoltDB
    • Kafka
    • NATS
    • SQS
  • 🕸️HTTP
    • Intro into HTTP
    • Headers and CORS
    • Proxy IP parser
    • Static files
    • X-Sendfile
    • Streaming
    • gzip
  • 📈Logging and Observability
    • OpenTelemetry
    • HealthChecks
    • Access Logs
    • AppLogger
    • Metrics
    • Grafana
    • Logger
  • 🔀Workflow Engine
    • Temporal.io
    • Worker
  • 🧩Integrations
    • Migration from RRv1 to RRv2
    • Spiral Framework
    • Yii
    • Symfony
    • Laravel
    • ChubbyPHP
  • 🧪Experimental Features
    • List of the Experimental Features
  • 🚨Error codes
    • CRC validation failed
    • Allocate Timeout
  • 📚Releases
    • v2025.1.1
    • v2025.1.0
    • v2024.3.5
    • v2024.3.4
    • v2024.3.3
    • v2024.3.2
    • v2024.3.1
    • v2024.3.0
Powered by GitBook
On this page
  • Manual restarting
  • Restarting in Docker container
  • Debug Mode
  • RoadRunner-Temporal Debug Mode
  • Stop Command

Was this helpful?

Edit on GitHub
  1. PHP Worker

Developer mode

When RoadRunner starts workers, they operate in daemon mode. In this mode, you need to reload the server every time you make changes to your codebase.

Manual restarting

One of the way reloading server is using console command:

./rr reset

This command is also helpful when you need to restart a remote RoadRunner server using a local RoadRunner client.

Restarting in Docker container

For example, you can use this command to restart workers inside a Docker container. To do this, you need to configure the RoadRunner server to handle external RPC requests by adding the following lines to your configuration file:

.rr.yaml
rpc:
  listen: tcp://:6001

You must also forward/expose port 6001 in your Docker container to be able to use this feature.

Now when you run the command, RoadRunner client sends RPC request to the running server.

Pay attention to the RPC host and port which uses RoadRunner client specified in the .rr.yaml should be the same as the RPC host and port which uses RoadRunner server. By default, client uses 127.0.0.1:6001.

Debug Mode

It can be a time-consuming and tedious process to restart workers manually, especially during the development phase of a project. To address this issue, RoadRunner provides a debug mode that automatically restarts workers after each handled request, allowing developers to make changes to their codebase without having to manually reload the server each time.

To enable debug mode, you can set the pool.debug option to true in desired plugin section that has workers pool:

.rr.yaml
http:
  pool:
    debug: true
    num_workers: 4

Or if you have only debug option in the pool section you can use short syntax:

.rr.yaml
http:
  pool.debug: true

Every plugin in RoadRunner that creates workers has a pool section in which you can activate debug mode.

When using the pool.debug option in RoadRunner, it is important to note that settings in pool section would work differently. All options will be ignored (supervisor, max_jobs, num_workers, etc.). This is because, in debug mode, RoadRunner does not create a worker at startup. Instead, it waits for requests to come in and creates workers accordingly. After the response, RoadRunner stops and removes the worker. When you send 2-3-n parallel requests to RoadRunner, it creates 2-3-n workers to handle those requests simultaneously. The number of workers depends on the number of requests you send. Similarly, when you use the Jobs plugin and the Jobs consumers, every message consumed creates a worker to handle that message. The number of workers is based on the number of messages consumed.

This enables you to make changes to your codebase and reload it automatically.

RoadRunner-Temporal Debug Mode

Note, that in the Temporal plugin, pool is actually called activities. All other pool options are the same. For example, pool.num_workers is activities.num_workers.

Stop Command

In RoadRunner, you can send a stop command from the worker to the parent server to force process destruction. When this happens, the job/request will be automatically forwarded to the next worker in the queue.

You can use this feature to implement max_jobs control on the PHP side. This can be useful for controlling memory usage inside the PHP script or for managing long-running tasks that need to be periodically restarted.

worker.php
<?php

use Spiral\RoadRunner;
use Nyholm\Psr7;

include "vendor/autoload.php";

$worker = RoadRunner\Worker::create();
$psrFactory = new Psr7\Factory\Psr17Factory();

$worker = new RoadRunner\Http\PSR7Worker($worker, $psrFactory, $psrFactory, $psrFactory);

$count = 0;
while ($req = $worker->waitRequest()) {
    try {
        $rsp = new Psr7\Response();
        $rsp->getBody()->write('Hello world!');

        $count++;
        if ($count > 10) {
            $worker->getWorker()->stop();
            return;
        }

        $worker->respond($rsp);
    } catch (\Throwable $e) {
        $worker->getWorker()->error((string)$e);
    }
}

As you can see in the example above, we send a stop command after handling 10 requests, to force process destruction. This ensures that the script does not consume too much memory and avoids any potential memory leaks.

PreviousWorkers poolNextCode Coverage

Last updated 5 months ago

Was this helpful?

👷