Worker
RoadRunner is a high-performance PHP application server designed to handle a large number of requests simultaneously. It does so by running your PHP application in the form of workers, which follow the shared-nothing architecture. Each worker represents an individual process, ensuring isolation and independence in their operation.
In this section, you will learn how to create a PHP worker that handles HTTP requests and returns a response to the RoadRunner server.
Creating a worker
Worker types
RoadRunner provides several plugins that use workers to receive requests, including HTTP, Jobs, Centrifuge, gRPC, TCP, and Temporal. You should choose the appropriate plugin based on the requirements of your application. In the examples below, we will explore the creation of an HTTP worker and a simple implementation of an entry point that can handle several types of requests.
Simple HTTP Worker
To create HTTP worker, you need to install the required composer packages:
After installing the required packages, you can create a worker. Here is an example of the simplest entry point with the PSR-7 server API:
This worker expects communication with the RoadRunner server over standard pipes.
Create a .rr.yaml
configuration file to enable it:
Read more about the configuration HTTP in the HTTP Plugin section.
Single entry point
In the example below, we will create a single entry point capable of processing incoming HTTP requests and requests from the queue system. RoadRunner provides the RR_MODE
environment variable, which allows us to determine the type of request received. We can then instantiate the appropriate worker, process the incoming request, return the response, and handle any potential exceptions. In this example, we strive to minimize dependencies and reduce the amount of code to the maximum extent possible. The sole objective of this example is to demonstrate how to handle various types of requests.
First of all, we need to install the required composer packages:
Let's start by creating an enum to enumerate the possible operating modes of RoadRunner. In this example, we will only require the values http and jobs, but we will list all available modes:
To split the logic for handling different types of requests, let's introduce the concept of a dispatcher. It will determine whether it can handle an incoming request and process it. We'll define an interface for dispatchers, which will include two methods: canServe - responsible for determining if the dispatcher can handle the request or not, and serve - intended to process the request if the canServe method returns true:
Let's implement the two dispatchers we need. One for handling HTTP requests and the other for processing requests from the queuing system:
In the canServe
method of both dispatchers, we use the Spiral\RoadRunner\EnvironmentInterface
interface provided by the spiral/roadrunner-worker package. This interface provides the getMode
method, which returns the current mode of RoadRunner as a string. The implementation of this interface, provided by the package, determines the mode based on the RR_MODE
environment variable.
The serve
method creates the worker and processes the incoming request. In the HttpDispatcher, we've used code from the above HTTP worker example, while in the QueueDispatcher, we instantiate the Spiral\RoadRunner\Jobs\Consumer
class provided by the spiral/roadrunner-jobs package. In a loop, we retrieve and handle incoming tasks. Both methods are significantly simplified, lacking real processing logic for requests. They send a string response to the browser and output the task object to the console.
Now, let's create an entry point that will be specified in the RoadRunner configuration file and will use our dispatchers:
The Roadrunner Bridge package, which provides the integration of RoadRunner into the Spiral Framework embodies this concept, and you may explore it if you wish to delve deeper into this topic.
Create a .rr.yaml
configuration file:
Read more about the RoadRunner configuration.
Now you can start the RoadRunner server by running the following command:
Read more about how to download and install RoadRunner in the RoadRunner β Installation section.
Error Handling
There are multiple ways to handle errors produced by PHP workers in RoadRunner. The simplest and most common way is to respond to the parent service with the error message using $psr7->getWorker()->error()
method.
Here's an example:
Another way to handle errors is to flush warnings and errors to STDERR
to output them directly into the console.
Here's an example:
Since RoadRunner 2.0 all warnings send to STDOUT
will be forwarded to STDERR
as well.
Communication Methods
By default, workers use standard pipes STDOUT
and STDERR
to exchange data frames with the RoadRunner server. However, in some cases, you may want to use alternative communication methods such as TCP
or unix
sockets.
Process supervision
RoadRunner provides process supervision capabilities to monitor your application and perform a soft reset between requests if necessary. You can configure process supervision for your application by editing your .rr.yaml
configuration file and specifying the necessary limits.
Here's an example configuration:
Please pay attention, that the RRv1 section had the name limit, >=v2.0
- supervisor
Troubleshooting
In some cases, RoadRunner may not be able to handle errors produced by the PHP worker, such as if PHP is missing or the script has died.
If this happens, you can troubleshoot the issue by invoking the command
specified in your .rr.yaml
file manually.
If there are any errors or issues with the script, they should be visible in the output of this command.
The worker should not cause any errors until any input is provided, and it should fail with an invalid input signature after the first input character. If this is not the case, there may be an issue with the PHP script or the way it is interacting with RoadRunner.
What's Next?
Plugins β Server - Read more about RoadRunner server plugin.
Last updated