├── .github ├── FUNDING.yml └── workflows │ ├── CI.yml │ └── links_checker.yml ├── .gitignore ├── README.md ├── docs └── en │ ├── app-server │ ├── aws-lambda.md │ ├── cli.md │ ├── images.md │ ├── nginx+RR │ │ ├── .rr.yaml │ │ ├── Dockerfile │ │ ├── composer.json │ │ ├── default.conf │ │ ├── docker-compose.yaml │ │ └── worker.php │ ├── nginx-with-rr.md │ ├── production.md │ └── systemd.md │ ├── customization │ ├── build.md │ ├── embedding.md │ ├── events-bus.md │ ├── middleware.md │ └── plugin.md │ ├── experimental │ └── experimental.md │ ├── http │ ├── cache.md │ ├── gzip.md │ ├── headers.md │ ├── http.md │ ├── resp-streaming.md │ ├── sendfile.md │ └── static.md │ ├── integration │ ├── cake.md │ ├── chubbyphp.md │ ├── codeigniter.md │ ├── laravel.md │ ├── mezzio.md │ ├── migration.md │ ├── phalcon.md │ ├── slim.md │ ├── spiral.md │ ├── symfony.md │ ├── symlex.md │ ├── template.md │ ├── ubiquity.md │ ├── yii.md │ └── zend.md │ ├── intro │ ├── about.md │ ├── config.md │ ├── contributing.md │ ├── features.md │ └── install.md │ ├── known-issues │ ├── allocate-timeout.md │ └── stdout-crc.md │ ├── kv │ ├── boltdb.md │ ├── memcached.md │ ├── memory.md │ ├── overview.md │ └── redis.md │ ├── lab │ ├── access-logs.md │ ├── applogger.md │ ├── dashboards │ │ ├── dashboards.md │ │ ├── grpc.md │ │ ├── http.md │ │ ├── jobs.md │ │ └── temporal.md │ ├── health.md │ ├── logger.md │ ├── metrics.md │ └── otel.md │ ├── license.md │ ├── manifest.json │ ├── php │ ├── debugging.md │ ├── developer.md │ ├── environment.md │ ├── rpc.md │ ├── scaling.md │ └── worker.md │ ├── plugins │ ├── centrifuge.md │ ├── config.md │ ├── grpc.md │ ├── intro.md │ ├── locks.md │ ├── server.md │ ├── service.md │ └── tcp.md │ ├── queues │ ├── amqp.md │ ├── beanstalk.md │ ├── boltdb.md │ ├── kafka.md │ ├── memory.md │ ├── nats.md │ ├── overview.md │ └── sqs.md │ ├── releases │ ├── v2-12-0.md │ ├── v2-12-1.md │ ├── v2-12-2.md │ ├── v2-12-3.md │ ├── v2023-1-0.md │ ├── v2023-1-1.md │ ├── v2023-1-2.md │ ├── v2023-1-3.md │ ├── v2023-1-4.md │ ├── v2023-1-5.md │ ├── v2023-2-0.md │ ├── v2023-2-1.md │ ├── v2023-2-2.md │ ├── v2023-3-0.md │ ├── v2023-3-1.md │ ├── v2023-3-2.md │ ├── v2023-3-3.md │ ├── v2023-3-4.md │ ├── v2023-3-5.md │ ├── v2023-3-6.md │ ├── v2023-3-7.md │ ├── v2023-3-8.md │ └── v2023-3-9.md │ ├── resources │ ├── kv-general-info.psd │ ├── queue-general-info.psd │ └── queue-rr-env-mode.psd │ └── workflow │ ├── temporal.md │ └── worker.md └── languages.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: roadrunner-server 4 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | misspell: 12 | # Check if the PR is not from a fork 13 | if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout on push 17 | if: github.event_name == 'push' 18 | uses: actions/checkout@v2 19 | - name: Checkout on pull_request 20 | if: github.event_name == 'pull_request' 21 | uses: actions/checkout@v2 22 | with: 23 | ref: ${{ github.head_ref }} 24 | - name: reviewdog fixer 25 | uses: reviewdog/action-misspell@v1 26 | with: 27 | github_token: ${{ secrets.GITHUB_TOKEN }} 28 | locale: "US" 29 | - name: sobolevn fixer 30 | uses: sobolevn/misspell-fixer-action@master 31 | - uses: peter-evans/create-pull-request@v3 32 | with: 33 | token: ${{ secrets.GITHUB_TOKEN }} 34 | commit-message: 'Typos fixes' 35 | title: "Typos fixes" 36 | branch: typos 37 | branch-suffix: timestamp 38 | -------------------------------------------------------------------------------- /.github/workflows/links_checker.yml: -------------------------------------------------------------------------------- 1 | name: Links Checker 2 | 3 | on: 4 | ## Allow triggering this workflow manually via GitHub CLI/web 5 | workflow_dispatch: 6 | 7 | ## Run this workflow automatically every month 8 | schedule: 9 | - cron: '30 5,17 * * *' 10 | 11 | jobs: 12 | link_checker: 13 | name: Check links and create automated issue if needed 14 | runs-on: ubuntu-latest 15 | timeout-minutes: 5 16 | env: 17 | REPORT_FILE: links-report 18 | steps: 19 | ## Check out code using Git 20 | - uses: actions/checkout@v2 21 | 22 | - name: Check all links at README.md and translations files 23 | id: lychee 24 | uses: lycheeverse/lychee-action@v1.2.0 25 | with: 26 | output: ${{ env.REPORT_FILE }} 27 | format: markdown 28 | ## Do not fail this step on broken links 29 | fail: false 30 | ## Allow pages replying with 200 (Ok), 204 (No Content), 31 | ## 206 (Partial Content) in at most 20 seconds with HTML content. 32 | args: >- 33 | --verbose 34 | --accept 200,204,206 35 | --timeout 20 36 | --max-concurrency 10 37 | --no-progress 38 | --exclude-loopback 39 | --exclude-link-local 40 | --exclude-mail 41 | docs/en/app-server/*.md docs/en/docker/*.md docs/en/integration/*.md docs/en/intro/*.md docs/en/known-issues/*.md docs/en/middleware/*.md docs/en/php/*.md docs/en/plugins/*.md docs/en/workflow/*.md 42 | env: 43 | ## Avoid rate limiting when checking github.com links 44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 45 | 46 | - name: Lychee's exit code 47 | ## https://github.com/lycheeverse/lychee#exit-codes 48 | run: echo Lychee exit with ${{ steps.lychee.outputs.exit_code }} 49 | 50 | - name: Find the last report issue open 51 | uses: micalevisk/last-issue-action@v1 52 | id: last_issue 53 | with: 54 | state: open 55 | labels: | 56 | report 57 | automated issue 58 | env: 59 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 60 | 61 | - name: Create issue from report file 62 | if: ${{ steps.last_issue.outputs.has_found == 'false' }} 63 | uses: peter-evans/create-issue-from-file@v3 64 | with: 65 | title: Link checker report 66 | content-filepath: ${{ env.REPORT_FILE }} 67 | issue-number: ${{ steps.last_issue.outputs.issue_number }} 68 | labels: | 69 | report 70 | automated issue 71 | - name: Update last report open issue created 72 | if: ${{ steps.last_issue.outputs.has_found == 'true' }} 73 | uses: peter-evans/create-issue-from-file@v3 74 | with: 75 | title: Link checker report 76 | content-filepath: ${{ env.REPORT_FILE }} 77 | issue-number: ${{ steps.last_issue.outputs.issue_number }} 78 | labels: | 79 | report 80 | automated issue 81 | - name: Close last report open issue 82 | if: ${{ steps.lychee.outputs.exit_code == 0 }} 83 | uses: peter-evans/close-issue@v1 84 | with: 85 | issue-number: ${{ steps.last_issue.outputs.issue_number }} 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NEW DOCS ARE HERE: [LINK](https://github.com/roadrunner-server/docs) 2 | 3 |

4 | 5 | 6 | 7 | 8 | 9 | 10 |

11 |

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | All releases 22 |

23 | 24 | RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. 25 | It supports running as a service with the ability to extend its functionality on a per-project basis. 26 | 27 | ## Contributors 28 | 29 | Thanks to all the people who already contributed! 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/en/app-server/images.md: -------------------------------------------------------------------------------- 1 | # App server — Docker Images 2 | 3 | Following Docker images are available: 4 | 5 | | Description | Links | Status | 6 | |------------------------------------------|-----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 7 | | **Official RR image** | [Link](https://github.com/roadrunner-server/roadrunner/pkgs/container/roadrunner) | ![Latest Stable Version](https://img.shields.io/github/v/release/roadrunner-server/roadrunner.svg?maxAge=30) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) | 8 | | **Third party image from `n1215`** | [Link](https://github.com/n1215/roadrunner-docker-skeleton) | [![License](https://poser.pugx.org/n1215/roadrunner-docker-skeleton/license)](https://packagist.org/packages/n1215/roadrunner-docker-skeleton) | 9 | | **Third party image from `spacetab-io`** | [Link](https://github.com/spacetab-io/docker-roadrunner-php) | ![Latest Stable Version](https://img.shields.io/github/v/release/spacetab-io/docker-roadrunner-php) ![License](https://img.shields.io/github/license/spacetab-io/docker-roadrunner-php) | 10 | 11 | 12 | Here is an example of a `Dockerfile` that can be used to build a Docker image with RoadRunner for a PHP application: 13 | 14 | ```dockerfile 15 | FROM php:8.2-cli-alpine3.17 as backend 16 | 17 | RUN --mount=type=bind,from=mlocati/php-extension-installer:1.5,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \ 18 | install-php-extensions opcache zip xsl dom exif intl pcntl bcmath sockets && \ 19 | apk del --no-cache ${PHPIZE_DEPS} ${BUILD_DEPENDS} 20 | 21 | WORKDIR /app 22 | 23 | ENV COMPOSER_ALLOW_SUPERUSER=1 24 | COPY --from=composer:2.3 /usr/bin/composer /usr/bin/composer 25 | 26 | # Copy composer files from app directory to install dependencies 27 | COPY ./app/composer.* . 28 | RUN composer install --optimize-autoloader --no-dev 29 | 30 | COPY --from=ghcr.io/roadrunner-server/roadrunner:2023.1.1 /usr/bin/rr /app 31 | 32 | EXPOSE 8080/tcp 33 | 34 | # Copy application files 35 | COPY ./app . 36 | 37 | # Run RoadRunner server 38 | CMD ./rr serve -c .rr.yaml 39 | ``` -------------------------------------------------------------------------------- /docs/en/app-server/nginx+RR/.rr.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | rpc: 4 | listen: tcp://127.0.0.1:6001 5 | 6 | server: 7 | command: "php worker.php" 8 | relay: pipes 9 | 10 | http: 11 | address: 0.0.0.0:80 12 | pool: 13 | num_workers: 10 14 | fcgi: 15 | address: tcp://0.0.0.0:9000 16 | 17 | logs: 18 | encoding: json 19 | level: error 20 | mode: production -------------------------------------------------------------------------------- /docs/en/app-server/nginx+RR/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/roadrunner-server/roadrunner:latest as roadrunner 2 | FROM --platform=${TARGETPLATFORM:-linux/amd64} php:8.1-alpine 3 | 4 | COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer 5 | COPY --from=roadrunner /usr/bin/rr /usr/local/bin/rr 6 | COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ 7 | 8 | RUN install-php-extensions sockets 9 | 10 | WORKDIR /src 11 | 12 | COPY worker.php /src 13 | COPY .rr.yaml /src 14 | COPY composer.json /src 15 | 16 | RUN composer install 17 | 18 | ENTRYPOINT ["rr"] 19 | -------------------------------------------------------------------------------- /docs/en/app-server/nginx+RR/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "minimum-stability": "dev", 3 | "prefer-stable": true, 4 | "require": { 5 | "guzzlehttp/guzzle": "^6.5", 6 | "nyholm/psr7": "^1.5", 7 | "spiral/roadrunner": "^2.0", 8 | "spiral/roadrunner-http": "^2.1", 9 | "spiral/roadrunner-worker": "^2.2", 10 | "spiral/goridge": "^3.2" 11 | } 12 | } -------------------------------------------------------------------------------- /docs/en/app-server/nginx+RR/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name RoadRunner; 5 | 6 | # http://roadrunner here is the DNS inside the docker 7 | location / { 8 | fastcgi_pass roadrunner:9000; 9 | # include the fastcgi_param setting 10 | include fastcgi_params; 11 | # proxy_pass http://roadrunner; 12 | access_log off; 13 | error_log off; 14 | # proxy_set_header Host $host; 15 | # proxy_set_header X-Forwarded-For $remote_addr; 16 | # proxy_set_header X-Forwarded-Port $server_port; 17 | # proxy_set_header X-Forwarded-Host $host; 18 | # proxy_set_header X-Forwarded-Proto $scheme; 19 | # proxy_read_timeout 1200s; 20 | } 21 | 22 | error_page 500 502 503 504 /50x.html; 23 | location = /50x.html { 24 | root /usr/share/nginx/html; 25 | } 26 | } -------------------------------------------------------------------------------- /docs/en/app-server/nginx+RR/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | roadrunner: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | # if needed to control the RR from the outside 9 | ports: 10 | - "127.0.0.1:6001:6001" 11 | command: 12 | - "serve" 13 | - "-c" 14 | - "/src/.rr.yaml" 15 | networks: 16 | nginx-docs: 17 | 18 | web: 19 | image: nginx:stable-alpine 20 | ports: 21 | - "8080:80" 22 | volumes: 23 | - ./:/etc/nginx/conf.d 24 | environment: 25 | - NGINX_PORT=80 26 | networks: 27 | nginx-docs: 28 | 29 | networks: 30 | nginx-docs: 31 | name: nginx-docs 32 | -------------------------------------------------------------------------------- /docs/en/app-server/nginx+RR/worker.php: -------------------------------------------------------------------------------- 1 | waitRequest()) { 20 | try { 21 | $resp = new \Nyholm\Psr7\Response(); 22 | $resp->getBody()->write("Hello from the RoadRunner :)"); 23 | 24 | $psr7->respond($resp); 25 | } catch (\Throwable $e) { 26 | $psr7->getWorker()->error((string)$e); 27 | } 28 | } -------------------------------------------------------------------------------- /docs/en/app-server/nginx-with-rr.md: -------------------------------------------------------------------------------- 1 | # App server — Nginx with RoadRunner 2 | 3 | RoadRunner seamlessly integrates with various web servers like Nginx, providing a powerful backend solution for 4 | processing PHP requests. 5 | 6 | ## Nginx configuration 7 | 8 | ### FastCGI 9 | 10 | RoadRunner can be configured to listen for FastCGI requests on a specific port. (Disabled by default.) 11 | 12 | ```yaml .rr.yaml 13 | version: "3" 14 | 15 | http: 16 | fcgi: 17 | address: tcp://0.0.0.0:9000 18 | ``` 19 | 20 | The FastCGI method allows Nginx to communicate directly with the RoadRunner server using the FastCGI protocol. This 21 | method is suitable when both Nginx and RoadRunner are running on the same machine. 22 | 23 | > **Warning** 24 | > Remember to adjust the configuration examples according to your specific environment and requirements. If RoadRunner 25 | > and Nginx are running in separate Docker containers, utilize the container DNS names (e.g., `roadrunner:9000`) instead 26 | > of IP addresses in the Nginx configuration. 27 | 28 | ```nginx docker/nginx/rr.conf 29 | server { 30 | listen 80; 31 | listen [::]:80; 32 | server_name _; 33 | 34 | location / { 35 | fastcgi_pass 127.0.0.1:9000; 36 | include fastcgi_params; 37 | 38 | access_log off; 39 | error_log off; 40 | } 41 | } 42 | ``` 43 | 44 | > **Note** 45 | > Consider using `fastcgi_pass` instead of `proxy_pass`: Using the `fastcgi_pass` directive might offer better 46 | > performance in certain configurations. 47 | 48 | ### Proxy 49 | 50 | RoadRunner can be configured to listen for HTTP requests on a specific port. 51 | 52 | ```yaml .rr.yaml 53 | http: 54 | address: 0.0.0.0:8080 55 | ``` 56 | 57 | > **Note** 58 | > Read more about configuring HTTP server in the [HTTP Plugin](../http/http.md) section. 59 | 60 | The Proxy method involves configuring Nginx to act as a reverse proxy for RoadRunner. Nginx receives client requests and 61 | forwards them to RoadRunner for processing. This method is useful when both are running on separate machines or when 62 | additional load balancing or caching features are required. 63 | 64 | > **Warning** 65 | > Remember to adjust the configuration examples according to your specific environment and requirements. If RoadRunner 66 | > and Nginx are running in separate Docker containers, utilize the container DNS names (e.g., `roadrunner:8080`) instead 67 | > of IP addresses in the Nginx configuration. 68 | 69 | ```nginx docker/nginx/rr.conf 70 | server { 71 | listen 80; 72 | listen [::]:80; 73 | server_name _; 74 | 75 | location / { 76 | proxy_pass http://127.0.0.1:8080; 77 | proxy_set_header Host $host; 78 | proxy_set_header X-Forwarded-For $remote_addr; 79 | proxy_set_header X-Forwarded-Port $server_port; 80 | proxy_set_header X-Forwarded-Host $host; 81 | proxy_set_header X-Forwarded-Proto $scheme; 82 | proxy_read_timeout 1200s; 83 | } 84 | ``` 85 | 86 | ### WebSocket proxy 87 | 88 | To enable WebSocket connections using Nginx proxy, you need to configure the proxy accordingly. 89 | 90 | This can be done by including the following configuration in the Nginx configuration file: 91 | 92 | ```nginx docker/nginx/rr.conf 93 | map $http_upgrade $connection_upgrade { 94 | default upgrade; 95 | '' close; 96 | } 97 | 98 | server { 99 | listen 80; 100 | listen [::]:80; 101 | server_name _; 102 | 103 | location /connection/websocket { 104 | proxy_pass http://127.0.0.1:8000/connection/websocket; 105 | proxy_http_version 1.1; 106 | proxy_set_header Upgrade $http_upgrade; 107 | proxy_set_header Connection $connection_upgrade; 108 | proxy_set_header Host $host; 109 | } 110 | 111 | location / { 112 | proxy_pass http://127.0.0.1:9000; 113 | # ... 114 | } 115 | } 116 | ``` 117 | 118 | > **Warning** 119 | > `http://127.0.0.1:8000` is the default address for the Centrifugo WebSocket server and `/connection/websocket` is the 120 | > default path for Bidirectional WebSocket connections. 121 | 122 | The location `/connection` block defines the path where WebSocket connections will be handled. 123 | 124 | ## Docker 125 | 126 | In this example, we will demonstrate how to use RoadRunner with Nginx in a Docker environment. 127 | 128 | ### Dockerfile 129 | 130 | ```docker docker/app/Dockerfile 131 | FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/roadrunner-server/roadrunner:latest as roadrunner 132 | FROM --platform=${TARGETPLATFORM:-linux/amd64} php:8.1-alpine 133 | 134 | COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer 135 | COPY --from=roadrunner /usr/bin/rr /usr/local/bin/rr 136 | COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ 137 | 138 | RUN mkdir /src 139 | COPY worker.php /src 140 | COPY .rr.yaml /src 141 | COPY composer.json /src 142 | 143 | WORKDIR /src 144 | 145 | RUN apk update 146 | RUN install-php-extensions sockets 147 | 148 | RUN composer install 149 | 150 | ENTRYPOINT ["rr"] 151 | ``` 152 | 153 | ### RoadRunner configuration 154 | 155 | Create a `.rr.yaml` configuration file to specify how RoadRunner should interact with your PHP application 156 | 157 | ```yaml .rr.yaml 158 | version: '3' 159 | 160 | rpc: 161 | listen: tcp://127.0.0.1:6001 162 | 163 | server: 164 | command: "php worker.php" 165 | relay: pipes 166 | 167 | http: 168 | address: 0.0.0.0:8080 169 | fcgi: 170 | address: tcp://0.0.0.0:9000 171 | pool: 172 | num_workers: 10 173 | 174 | logs: 175 | encoding: json 176 | level: error 177 | mode: production 178 | ``` 179 | 180 | ### PHP Worker 181 | 182 | Create a PHP worker to handle the HTTP requests. 183 | 184 | **Here is a simple example:** 185 | 186 | ```php worker.php 187 | waitRequest()) { 203 | try { 204 | $resp = new \Nyholm\Psr7\Response(); 205 | $resp->getBody()->write("Hello from the RoadRunner :)"); 206 | 207 | $psr7->respond($resp); 208 | } catch (\Throwable $e) { 209 | $psr7->getWorker()->error((string)$e); 210 | } 211 | } 212 | ``` 213 | 214 | And do not forget about the `composer.json` file: 215 | 216 | ```json composer.json 217 | { 218 | "minimum-stability": "dev", 219 | "prefer-stable": true, 220 | "require": { 221 | "spiral/roadrunner-http": "^3.0", 222 | "spiral/goridge": "^4.0" 223 | } 224 | } 225 | ``` 226 | 227 | > **Note** 228 | > Read more about the RoadRunner PHP Worker in the [PHP Workers](../php/worker.md) section. 229 | 230 | ### Docker Compose 231 | 232 | To assemble and manage all components, create a `docker-compose.yaml` file that defines the RoadRunner and Nginx 233 | services, as well as their configurations 234 | 235 | ```yaml docker-compose.yaml 236 | version: "3.8" 237 | 238 | services: 239 | roadrunner: 240 | build: 241 | context: . 242 | dockerfile: docker/app/Dockerfile 243 | ports: 244 | - "127.0.0.1:6001:6001" 245 | command: 246 | - "serve" 247 | - "-c" 248 | - "/src/.rr.yaml" 249 | networks: 250 | nginx-docs: 251 | 252 | web: 253 | image: nginx:stable-alpine 254 | ports: 255 | - "8080:80" 256 | volumes: 257 | - ./docker/nginx:/etc/nginx/conf.d 258 | environment: 259 | - NGINX_PORT=80 260 | networks: 261 | nginx-docs: 262 | 263 | networks: 264 | nginx-docs: 265 | name: nginx-docs 266 | ``` 267 | 268 | > **Note** 269 | > Store one of the configuration files provided in the [Nginx configuration](#nginx-configuration) section in 270 | > the `docker/nginx` directory. -------------------------------------------------------------------------------- /docs/en/app-server/production.md: -------------------------------------------------------------------------------- 1 | # App server — Production Usage 2 | 3 | When utilizing RoadRunner in a production environment, it is important to consider various tips and suggestions to 4 | ensure optimal performance and stability. 5 | 6 | ## State and memory 7 | 8 | One crucial aspect to keep in mind is that state and memory are **not shared** between different worker instances, but 9 | they are **shared** for a single worker instance. As a result, it is essential to take precautions such as closing all 10 | descriptors and avoiding state pollution to prevent memory leaks and ensure application stability. 11 | 12 | **Here are some tips to keep in mind:** 13 | 14 | - Make sure you close all descriptors (especially on fatal exceptions). 15 | - Watch out for memory leaks - you need to be more selective about the components you use. Workers will be restarted in 16 | case of a memory leak, but it should not be difficult to avoid this problem altogether by designing your application 17 | properly. 18 | - Avoid state pollution (i.e., caching globals or user data in memory). 19 | - Database connections and any `pipe`/`socket` are the potential point of failure. An easy way to deal with this is to 20 | close all connections after every iteration. Note that this is not the most performant solution. 21 | 22 | > **Warning** 23 | > Consider calling `gc_collect_cycles` after every execution if you want to keep memory usage low (this will slow down 24 | > your application a bit). 25 | 26 | ## Useful Tips 27 | 28 | - Make sure you are **NOT** listening on `0.0.0.0` in the RPC service (unless in Docker). 29 | - Connect to a worker using `pipes` for better performance (Unix sockets are just a bit slower). 30 | - Adjust your pool timings to the values you like. 31 | - **Number of workers = number of CPU threads** in your system, unless your application is IO bound, then choose the 32 | number heuristically based on the available memory on the server. 33 | - Consider using `max_jobs` for your workers if you experience application stability memory issues over time. 34 | - RoadRunner has +40% performance when using keep-alive connections. 35 | - Set the memory limit at least 10-20% below `max_memory_usage`. 36 | - Since RoadRunner runs workers from cli, you need to enable `OPcache` in the CLI with `opcache.enable_cli=1`. 37 | - Make sure to use [health check endpoint](../lab/health.md) when running `rr` in a cloud environment. 38 | - Use the `user` option in the `server` plugin configuration to start worker processes from the specified user on 39 | Linux-based systems. Note that in this case RoadRunner should be started from the `root` to allow fork-exec processes 40 | from different users. 41 | - If your application uses mostly IO (disk, network, etc), you can allocate as many workers as you have memory for the 42 | application. Workers are cheap. A hello-world worker uses no more than **~26Mb** of RSS memory. 43 | - For CPU bound operation, see an average CPU load and choose the number of workers to consume **90-95%** CPU. Leave a 44 | few percent for the GC of the GO (not necessary btw). 45 | - If you have `~const` workers latency, you can calculate the number of workers needed to handle the 46 | target [load](https://github.com/spiral/roadrunner/discussions/799#discussioncomment-1332646). 47 | -------------------------------------------------------------------------------- /docs/en/app-server/systemd.md: -------------------------------------------------------------------------------- 1 | # App server — Running server as daemon on Linux 2 | 3 | Here you can find an example of systemd unit file that can be used to run RoadRunner as a daemon on 4 | a server: 5 | 6 | ```ini 7 | [Unit] 8 | Description = High-performance PHP application server 9 | 10 | [Service] 11 | Type = simple 12 | ExecStart = /usr/local/bin/rr serve -c /var/www/.rr.yaml 13 | Restart = always 14 | RestartSec = 30 15 | 16 | [Install] 17 | WantedBy = default.target 18 | ``` 19 | 20 | Where is 21 | 22 | - `/usr/local/bin/rr` - path to the RoadRunner binary file 23 | - `/var/www/.rr.yaml` - path to the RoadRunner configuration file 24 | 25 | > **Warning** 26 | > These paths are just examples, and the actual paths may differ depending on the specific 27 | > server configuration and file locations. You should update these paths to match the actual paths used in your server 28 | > setup. 29 | 30 | You should also update the `ExecStart` option with your own configuration and save the file with a suitable name, 31 | such as `rr.service`. Usually, such user unit files are located in the `.config/systemd/user/` directory. To enable the 32 | service, you should run the following commands: 33 | 34 | ```bash 35 | systemctl enable --user rr.service 36 | ``` 37 | 38 | and 39 | 40 | ```bash 41 | systemctl start rr.service 42 | ``` 43 | 44 | This will start RoadRunner as a daemon on the server. 45 | 46 | For more information about systemd unit files, the user can refer to the 47 | following [link](https://wiki.archlinux.org/index.php/systemd#Writing_unit_files). 48 | 49 | ## SDNotify support 50 | 51 | RR supports SDNotify protocol. You can use it to notify systemd about the readiness of your application. You don't need 52 | to configure anything, RR will automatically detect systemd and send the notification. The only one option which might be 53 | configured is watchdog timeout. By default, it's turned off. You can enable it by setting the following option in your 54 | `.rr.yaml` config: 55 | 56 | ```yaml 57 | endure: 58 | log_level: error 59 | watchdog_sec: 60 # watchdog timeout in seconds 60 | ``` -------------------------------------------------------------------------------- /docs/en/customization/embedding.md: -------------------------------------------------------------------------------- 1 | # Customization — Embedding a Server 2 | 3 | In some cases, it can be useful to embed a RoadRunner server inside another GO program. This is often the case in 4 | microservice architectures where you may have a mandated GO framework for all the apps. In such cases it might not be 5 | possible to run a stock roadrunner instance and the only choice is to run roadrunner inside the main app framework / 6 | program. 7 | 8 | Here's an example of how to embed RoadRunner into a Go program with an HTTP handler: 9 | 10 | ```go 11 | func handleRequest(w http.ResponseWriter, request *http.Request) { 12 | // Find a way to pass that to RoadRunner so PHP handles the request 13 | } 14 | ``` 15 | 16 | ## Create an RR instance 17 | 18 | ```go 19 | overrides := []string{} // List of configuration overrides 20 | plugins := roadrunner.DefaultPluginsList() // List of RR plugins to enable 21 | rr, err := roadrunner.NewRR(".rr.yaml", overrides, plugins) 22 | ``` 23 | 24 | Here we use the default list of plugins. The same list of plugin you would get if you were to run `rr serve` with a 25 | stock roadrunner binary. 26 | 27 | You can however choose only the plugins you want and add your own private plugins as well: 28 | 29 | ```go 30 | overrides := []string{ 31 | "http.address=127.0.0.1:4444", // example override to set the http address 32 | "http.pool.num_workers=4", // example override of how to set the number of php workers 33 | } // List of configuration overrides 34 | plugins := []interface{}{ 35 | &informer.Plugin{}, 36 | &resetter.Plugin{}, 37 | // ... 38 | &httpPlugin.Plugin{}, 39 | // ... 40 | &coolCompany.Plugin{}, 41 | } 42 | rr, err := roadrunner.NewRR(".rr.yaml", overrides, plugins) 43 | ``` 44 | 45 | ## Passing requests to RoadRunner 46 | 47 | Roadrunner can respond to HTTP requests, but also gRPC ones or many more. Because this is all done via plugins that each 48 | listen to different types of requests, ports, etc... 49 | 50 | So when we talk about passing a request to roadrunner, we're actually talking about passing the request to roadrunner's 51 | HTTP plugin. To do this, we need to keep a handle on the http plugin. 52 | 53 | ```go 54 | overrides := []string{} // List of configuration overrides 55 | httpPlugin := &httpPlugin.Plugin{}, 56 | plugins := []interface{}{ 57 | &informer.Plugin{}, 58 | &resetter.Plugin{}, 59 | // ... 60 | httpPlugin, 61 | // ... 62 | &coolCompany.Plugin{}, 63 | } 64 | rr, err := roadrunner.NewRR(".rr.yaml", overrides, plugins) 65 | ``` 66 | 67 | The HTTP plugin is itself an `http.Handler` so it's now very easy to use it to let roadrunner and PHP handle the 68 | request: 69 | 70 | ```go 71 | overrides := []string{ 72 | // override the http plugin's address value for the current run of the program 73 | "http.address=127.0.0.1:4444", 74 | } // List of configuration overrides 75 | httpPlugin := &httpPlugin.Plugin{}, 76 | plugins := []interface{}{ 77 | &informer.Plugin{}, 78 | &resetter.Plugin{}, 79 | // ... 80 | httpPlugin, 81 | // ... 82 | &coolCompany.Plugin{}, 83 | } 84 | rr, err := roadrunner.NewRR(".rr.yaml", overrides, plugins) 85 | if err != nil { 86 | return err 87 | } 88 | 89 | func handleRequest(w http.ResponseWriter, request *http.Request) { 90 | return httpPlugin.ServeHTTP(w, request) 91 | } 92 | ``` 93 | 94 | ## Starting & Stopping Embedded Roadrunner 95 | 96 | Once everything is ready, we can start the roadrunner instance: 97 | 98 | ```go 99 | errCh := make(chan error, 1) 100 | go func() { 101 | errCh <- rr.Serve() 102 | }() 103 | ``` 104 | 105 | `rr.Serve()` will block until it returns an error or `nil` if it was stopped gracefully. 106 | 107 | To gracefully stop the server, we simply call `rr.Stop()` 108 | 109 | ## Roadrunner State 110 | 111 | When you run roadrunner, it goes through multiple phases of initialization, running, stopping etc... 112 | Sometimes it is useful to know about those, be it for debugging, to know if you're ready to accept requests, or if you 113 | can gracefully shutdown the main program. 114 | 115 | You can call `rr.CurrentState()` on your roadrunner instance to retrieve one of the following states: 116 | 117 | ```go 118 | package fsm 119 | // github.com/roadrunner-server/endure/pkg/fsm 120 | 121 | type State uint32 122 | 123 | const ( 124 | Uninitialized State = iota 125 | Initializing 126 | Initialized 127 | Starting 128 | Started 129 | Stopping 130 | Stopped 131 | Error 132 | ) 133 | ``` 134 | 135 | Additionally, the actual status name can be obtained via `rr.CurrentState().String()`. 136 | -------------------------------------------------------------------------------- /docs/en/customization/middleware.md: -------------------------------------------------------------------------------- 1 | # Customization — HTTP Middleware 2 | 3 | RoadRunner provides a flexible and extensible architecture that allows developers to build custom middleware for 4 | `http` and custom interceptors for `grpc` and `temporal` plugins. Moving highly loaded parts of an application, such as 5 | authentication, to middleware written in Go can provide a significant performance boost. By leveraging the speed and 6 | efficiency of Go, developers can improve the overall performance of their application and handle spikes in traffic more 7 | effectively. 8 | 9 | Middleware architecture allows developers to create custom middleware for their specific needs. The HTTP 10 | middleware can be used to intercept and modify HTTP requests and responses, while the gRPC interceptor can be used to 11 | intercept and modify gRPC requests and responses. This allows developers to add additional functionality to their 12 | applications without having to modify the core application logic. 13 | 14 | ## HTTP 15 | 16 | The HTTP middleware intercepts incoming HTTP requests and can be used to perform additional processing, such as 17 | authentication, rate limiting, and logging. 18 | 19 | **To create custom middleware for HTTP requests in RoadRunner, follow these steps:** 20 | 21 | 1. Define a struct that implements the `Init()`, `Middleware()`, and `Name()` methods. The `Init()` method is called 22 | when the plugin is initialized, the `Middleware()` method is called for each incoming HTTP request, and the `Name()` 23 | method returns the name of the middleware/plugin. 24 | 25 | 2. In the `Middleware()` method, perform any necessary processing on the incoming HTTP request, and then call the next 26 | middleware in the pipeline using the `next.ServeHTTP()` method. 27 | 28 | **Here is an example:** 29 | 30 | ```go 31 | package middleware 32 | 33 | import ( 34 | "net/http" 35 | ) 36 | 37 | const PluginName = "middleware" 38 | 39 | type Plugin struct{} 40 | 41 | // to declare plugin 42 | func (p *Plugin) Init() error { 43 | return nil 44 | } 45 | 46 | func (p *Plugin) Middleware(next http.Handler) http.Handler { 47 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 48 | // do something 49 | // ... 50 | // continue request through the middleware pipeline 51 | next.ServeHTTP(w, r) 52 | }) 53 | } 54 | 55 | // Middleware/plugin name. 56 | func (p *Plugin) Name() string { 57 | return PluginName 58 | } 59 | ``` 60 | 61 | > **Note** 62 | > Middleware must correspond to the 63 | > following [interface](https://github.com/roadrunner-server/http/blob/master/common/interfaces.go#L33) and 64 | > be [named](https://github.com/roadrunner-server/endure/blob/master/container.go#L47). 65 | 66 | ## gRPC 67 | 68 | The interceptor intercepts incoming gRPC requests and can be used to perform additional processing, such as 69 | authentication, rate limiting, and logging. 70 | 71 | **To create a custom interceptor for gRPC requests in RoadRunner, follow these steps:** 72 | 73 | 1. Define a struct that implements the `Init()`, `Interceptor()`, and `Name()` methods. The `Init() `method is called 74 | when the plugin is initialized, the `Interceptor()` method is called for each incoming gRPC request, and the `Name()` 75 | method returns the name of the middleware/plugin. 76 | 77 | 2. In the `Interceptor()` method, perform any necessary processing on the incoming gRPC request, and then call the next 78 | interceptor in the pipeline using the `handler(ctx, req)` method. 79 | 80 | > **Warning** 81 | > RoadRunner supports `gRPC` interceptors since `v2023.2.0` version. 82 | 83 | **Here is an example:** 84 | 85 | ```go 86 | package middleware 87 | 88 | import ( 89 | "net/http" 90 | ) 91 | 92 | const PluginName = "interceptor" 93 | 94 | type Plugin struct{} 95 | 96 | // to declare plugin 97 | func (p *Plugin) Init() error { 98 | return nil 99 | } 100 | 101 | func (p *Plugin) Interceptor() grpc.UnaryServerInterceptor { 102 | // Do something and return interceptor 103 | } 104 | 105 | // Middleware/plugin name. 106 | func (p *Plugin) Name() string { 107 | return PluginName 108 | } 109 | ``` 110 | 111 | > **Note** 112 | > Interceptor must correspond to the 113 | > following [interface](https://github.com/roadrunner-server/grpc/blob/master/common/interfaces.go#L14) and 114 | > be [named](https://github.com/roadrunner-server/endure/blob/master/container.go#L47). 115 | 116 | You can find a lot of examples here: [link](https://github.com/grpc-ecosystem/go-grpc-middleware). Keep in mind that, at 117 | the moment, RR supports only `UnaryServerInterceptor` gRPC interceptors. 118 | 119 | ## PSR7 Attributes 120 | 121 | PSR7 attributes are a way of attaching metadata to an incoming HTTP request or response. The PSR7 specification defines 122 | a standard interface for HTTP messages, which includes the ability to set and retrieve attributes on both requests and 123 | responses. 124 | 125 | Attributes can be used to store any kind of metadata that might be useful for processing the request or response. For 126 | example, you might use attributes to store information about the authenticated user, the user's IP address, or any other 127 | custom data that you want to attach to the request. 128 | 129 | The `Psr\Http\Message\ServerRequestInterface->getAttributes()` method can be used to retrieve attributes from an 130 | incoming HTTP request, while the `ResponseInterface->withAttribute()` method can be used to set attributes on an 131 | outgoing HTTP response. 132 | 133 | You can safely pass values to a PHP application and retrieve attributes on PHP side using 134 | the `Psr\Http\Message\ServerRequestInterface->getAttributes(`) 135 | through [attributes](https://github.com/roadrunner-server/http/blob/master/attributes/attributes.go) package: 136 | 137 | ```go 138 | func (s *Service) Middleware(next http.HandlerFunc) http.HandlerFunc { 139 | return func(w http.ResponseWriter, r *http.Request) { 140 | r = attributes.Init(r) 141 | attributes.Set(r, "key", "value") 142 | next.ServeHTTP(w, r) 143 | } 144 | } 145 | ``` 146 | 147 | > **Note** 148 | > To retrieve the attributes in a PHP application, you would need to use a PSR-7 implementation that supports 149 | > the `getAttributes()` method. For example, the `nyholm/psr7` package provides a PSR-7 implementation that supports it. 150 | 151 | ## Registering middleware 152 | 153 | You have to register this service after in 154 | the [container/plugin.go](https://github.com/roadrunner-server/roadrunner/blob/master/container/plugins.go) file in 155 | order to properly resolve dependency: 156 | 157 | ```go 158 | package roadrunner 159 | 160 | import ( 161 | "middleware" 162 | ) 163 | 164 | func Plugins() []any { 165 | return []any { 166 | // ... 167 | 168 | // middleware 169 | &middleware.Plugin{}, 170 | 171 | // ... 172 | } 173 | ``` 174 | 175 | Or you might use Velox tool to [build the RR binary](./build.md). 176 | 177 | You should also make sure you configure the middleware to be used via 178 | the [config or the command line](../intro/config.md). Otherwise, the plugin will be loaded, but the middleware will not 179 | be used with incoming requests. 180 | 181 | ```yaml .rr.yaml 182 | http: 183 | # provide the name of the plugin as provided by the plugin in the example's case, "middleware" 184 | middleware: [ "middleware" ] 185 | ``` 186 | 187 | ## Video tutorial 188 | 189 | ### Writing a middleware for HTTP 190 | 191 | [![Writing a middleware](https://img.youtube.com/vi/f5fUSYaDKxo/0.jpg)](https://www.youtube.com/watch?v=f5fUSYaDKxo) 192 | -------------------------------------------------------------------------------- /docs/en/experimental/experimental.md: -------------------------------------------------------------------------------- 1 | # Experimental Features 2 | 3 | ## Introduction 4 | Starting from the RR `v2023.3.4` release, we have introduced a new feature called **Experimental Features**. This feature allows you to try out new features that are not yet ready for production use. 5 | 6 | ## How to enable experimental features 7 | To enable experimental features, you need to run RR with the `-e` (`--enable-experimental`) flag. For example: 8 | 9 | ```bash 10 | ./rr serve -e 11 | ``` 12 | 13 | Or: 14 | 15 | ```bash 16 | ./rr serve --enable-experimental 17 | ``` 18 | 19 | ## List of experimental features 20 | 21 | ### Support for the nested configurations: `[>=2023.3.4]`. 22 | 23 | Using the following syntax, you may include other configuration files into the main one: 24 | 25 | ```yaml .rr.yaml 26 | version: "3" 27 | 28 | include: 29 | - .rr.include1-sub1.yaml 30 | - .rr.include1-sub2.yaml 31 | 32 | reload: 33 | interval: 1s 34 | patterns: [".php"] 35 | ``` 36 | Where `.rr.include1-sub1.yaml` and `.rr.include1-sub2.yaml` are the configuration files that are located in the same directory as the main configuration file. 37 | Includes override the main configuration file. For example, if you have the following nested configuration: 38 | 39 | ```yaml .rr.include1-sub1.yaml 40 | version: "3" 41 | 42 | server: 43 | command: "php php_test_files/psr-worker-bench.php" 44 | relay: pipes 45 | 46 | http: 47 | address: 127.0.0.1:15389 48 | middleware: 49 | - "sendfile" 50 | pool: 51 | allocate_timeout: 10s 52 | num_workers: 2 53 | ``` 54 | 55 | It will override the `server` and `http` sections of the main configuration file. 56 | You may use env variables in the included configuration files, but you can't use overrides for the nested configuration. For example: 57 | 58 | > **Note** 59 | > The next 'include' will override values set by the previous 'include'. Values in the root `.rr.yaml` will be overwritten by the includes as well. 60 | > Feel free to send us feedback on this feature. 61 | 62 | 63 | ```yaml .rr.include1-sub1.yaml 64 | version: "3" 65 | 66 | server: 67 | command: "${PHP_COMMAND:-php_test_files/psr-worker-bench.php}" 68 | relay: pipes 69 | ``` 70 | 71 | You may use any number of the included configuration files via CLI command, in quotas and separated by whitespace. For example: 72 | 73 | ```bash 74 | ./rr serve -e -c .rr.yaml -o include=".rr.yaml .rr2.yaml" 75 | ``` 76 | 77 | ### Support for loading [`envfiles`](https://github.com/roadrunner-server/roadrunner/issues/1077) in the `.rr.yaml`: `[>= v2023.3.5]` 78 | In the `v2023.3.5` added experimental support for loading `envfiles` in the `.rr.yaml` configuration file. 79 | `.env` file should be in the same directory as the `.rr.yaml` file. 80 | 81 | Sample `.rr.yaml` file: 82 | 83 | ```yaml .rr.yaml 84 | version: "3" 85 | envfile: .env 86 | ``` 87 | 88 | ### Support for the HTTP3 server: `[>=2023.3.8]`. 89 | In the `v2023.3.8` we added experimental support for the HTTP3 server. It can work with the ACME provider to generate certificates for the HTTP3 server automatically. 90 | 91 | Sample `.rr.yaml` file: 92 | 93 | ```yaml .rr.yaml 94 | version: "3" 95 | 96 | server: 97 | command: "php worker.php" 98 | relay: pipes 99 | 100 | http: 101 | address: 127.0.0.1:15389 102 | pool: 103 | num_workers: 2 104 | http3: 105 | address: 127.0.0.1:34555 106 | key: "localhost+2-key.pem" 107 | cert: "localhost+2.pem" 108 | ``` 109 | 110 | Or if you use ACME provider: 111 | 112 | ```yaml .rr.yaml 113 | version: "3" 114 | 115 | server: 116 | command: "php worker.php" 117 | relay: pipes 118 | 119 | http: 120 | address: 127.0.0.1:15389 121 | pool: 122 | num_workers: 2 123 | http3: 124 | address: 127.0.0.1:34555 125 | key: "localhost+2-key.pem" 126 | cert: "localhost+2.pem" 127 | ssl: 128 | acme: 129 | certs_dir: rr_le_certs 130 | email: you-email-here@email 131 | alt_http_port: 80 132 | alt_tlsalpn_port: 443 133 | challenge_type: http-01 134 | use_production_endpoint: false 135 | domains: 136 | - your-cool-domains.here 137 | ``` 138 | 139 | You may also generate testing certificates manually and use them in the configuration file. To do that, you may use [mkcert](https://github.com/FiloSottile/mkcert) or [certbot](https://certbot.eff.org/): 140 | 141 | ```bash 142 | mkcert -install && mkcert -client localhost 127.0.0.1 ::1 && mkcert localhost 127.0.0.1 ::1 143 | ``` 144 | 145 | This command will generate the client and server certificates for the `localhost` domain. You may use them in the configuration file: 146 | 147 | ```yaml .rr.yaml 148 | version: "3" 149 | 150 | server: 151 | command: "php worker.php" 152 | relay: pipes 153 | 154 | http: 155 | address: 127.0.0.1:15389 156 | pool: 157 | num_workers: 2 158 | http3: 159 | address: 127.0.0.1:34555 160 | key: "localhost+2-key.pem" # <- generated by mkcert: "localhost+2-key.pem" 161 | cert: "localhost+2.pem" # <- generated by mkcert: "localhost+2.pem" 162 | ``` 163 | 164 | Client certificates might be used in your favorite `http3` client. For example, you may use [curl3](https://curl.se/docs/http3.html) to test the HTTP3 server: 165 | 166 | ```bash 167 | curl3 --http3 -k --cert localhost+2.pem --key localhost+2-key.pem https://127.0.0.1:34555/ 168 | ``` 169 | 170 | ### OTLP support in the `gRPC` plugin: `[>=2023.3.8]`. 171 | In the `v2023.3.8` we added experimental support for the `OTLP` protocol in the `gRPC` plugin. To enable it, you need to activate `otel` plugin by adding the following lines to the `.rr.yaml` file: 172 | 173 | ```yaml .rr.yaml 174 | otel: # <- activate otel plugin 175 | resource: 176 | service_name: "rr_test_grpc" 177 | service_version: "1.0.0" 178 | service_namespace: "RR-gRPC" 179 | service_instance_id: "UUID-super-long-unique-id" 180 | insecure: false 181 | exporter: stderr 182 | ``` 183 | 184 | Trace keys passed to the PHP workers are: 185 | 1. `Traceparent` 186 | 2. `Uber-Trace-Id` 187 | 188 | Example: 189 | ```log 190 | "Traceparent":["00-2678b910f57fe3320587f4126a390868-6b87f1600005b643-01"],"Uber-Trace-Id":["2678b910f57fe3320587f4126a390868:6b87f1600005b643:0:1"] 191 | ``` 192 | 193 | More about `OTLP` plugin you may read [here](../lab/otel.md). -------------------------------------------------------------------------------- /docs/en/http/gzip.md: -------------------------------------------------------------------------------- 1 | # HTTP — Gzip middleware 2 | 3 | The gzip middleware is used to support the `accept-encodin: gzip` header and to compress and decompress the contents of the 4 | outgoing/incoming requests. 5 | 6 | ## Documentation 7 | 8 | - MDN [link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) 9 | 10 | ## Configuration 11 | 12 | ```yaml 13 | version: "3" 14 | 15 | http: 16 | address: 127.0.0.1:15389 17 | middleware: [ gzip ] 18 | pool: 19 | num_workers: 10 20 | allocate_timeout: 60s 21 | destroy_timeout: 60s 22 | ``` 23 | 24 | Gzip middleware supports OpenTelemetry headers propagation. 25 | -------------------------------------------------------------------------------- /docs/en/http/headers.md: -------------------------------------------------------------------------------- 1 | # HTTP — Headers and CORS 2 | 3 | Headers middleware is used to set up request/response headers and control CORS for your application. 4 | 5 | ## CORS 6 | 7 | To enable CORS headers add the following section to your configuration. 8 | 9 | ```yaml 10 | version: "3" 11 | 12 | http: 13 | address: 127.0.0.1:44933 14 | middleware: ["headers"] 15 | # ... 16 | headers: 17 | cors: 18 | allowed_origin: "*" 19 | # If `allowed_origin_regex` option is set, the content of `allowed_origin` is ignored 20 | allowed_origin_regex: "^http://foo" 21 | allowed_headers: "*" 22 | allowed_methods: "GET,POST,PUT,DELETE" 23 | allow_credentials: true 24 | exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma" 25 | max_age: 600 26 | # Status code to use for successful OPTIONS requests. Default value is 200. 27 | options_success_status: 200 28 | # Debugging flag adds additional output to debug server side CORS issues, consider disabling in production. 29 | debug: false 30 | ``` 31 | 32 | > Make sure to declare "headers" middleware. 33 | 34 | > **Note** 35 | > Since RoadRunner v2023.2.0 following changes were made: 36 | > ability to define status code of successful OPTIONS request via options_success_status config; 37 | > debug flag was added to enable additional output to debug CORS issues; 38 | > it's allowed to define multiple allowed_origin values separated by comma; 39 | > CORS requests are handled using [rs/cors](https://github.com/rs/cors) package. 40 | 41 | ## Custom headers for Response or Request 42 | 43 | You can control additional headers to be set for outgoing responses and headers to be added to the request sent to your application. 44 | ```yaml 45 | version: "3" 46 | 47 | http: 48 | # ... 49 | headers: 50 | # Automatically add headers to every request passed to PHP. 51 | request: 52 | Example-Request-Header: "Value" 53 | 54 | # Automatically add headers to every response. 55 | response: 56 | X-Powered-By: "RoadRunner" 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/en/http/resp-streaming.md: -------------------------------------------------------------------------------- 1 | # HTTP Response streaming `[>=2023.3]` 2 | 3 | RoadRunner supports HTTP response streaming. This feature means that responses can be sent to the client in chunks. It is useful when you need to send a large amount of data to the client. 4 | You don't need to update the configuration to enable this feature. It is enabled by default and controlled by the PHP worker. 5 | 6 | ## Samples 7 | 8 | ### Sending a response in chunks 9 | 10 | The size of the chunks is controlled by the PHP worker. You can send a chunk by calling the `respond()` method of the `Spiral\RoadRunner\Http\HttpWorker` class. 11 | The signature of the method is the following: 12 | ```php 13 | /** 14 | * @throws \JsonException 15 | */ 16 | public function respond(int $status, string|Generator $body = '', array $headers = [], bool $endOfStream = true): void 17 | ``` 18 | 19 | The `$body` parameter can be a string or a generator. If it is a generator, the worker will iterate over it and send chunks to the client. 20 | `$status` and `$headers` are the same as in the `respond()` method of the `Spiral\RoadRunner\Http\HttpWorker` class. 21 | The `$endOfStream` parameter indicates whether the response is finished. If set to false, the worker will wait for the next chunk. 22 | 23 | Here is the example of the streaming response: 24 | 25 | ```php 26 | waitRequest()) { 50 | $http->respond(200, $read()); 51 | } 52 | } catch (\Throwable $e) { 53 | $worker->error($e->getMessage()); 54 | } 55 | ``` 56 | 57 | ### Sending headers and status codes 58 | 59 | You can send headers and status codes (`1XX` multiple times, or other, but only once) to the client during the streaming. 60 | 61 | ```php 62 | waitRequest()) { 92 | $http->respond(100, '', headers: ['X-100' => ['100']], endOfStream: false); 93 | $http->respond(101, '', headers: ['X-101' => ['101']], endOfStream: false); 94 | $http->respond(102, '', headers: ['X-102' => ['102']], endOfStream: false); 95 | $http->respond(103, '', headers: ['Link' => ['; rel=preload; as=style'], 'X-103' => ['103']], endOfStream: false); 96 | $http->respond(200, $read(), headers: ['X-200' => ['200']], endOfStream: true); 97 | } 98 | } catch (\Throwable $e) { 99 | $worker->error($e->getMessage()); 100 | } 101 | ``` 102 | 103 | In this example, we send 5 status codes and 5 headers to the client. You may send a `103 Early Hints` status code (or any `1XX` status code) to the client at any time during streaming (do not forget about `$endOfStream`). -------------------------------------------------------------------------------- /docs/en/http/sendfile.md: -------------------------------------------------------------------------------- 1 | # HTTP — X-Sendfile middleware 2 | 3 | The `Send` HTTP middleware and the `X-Sendfile` HTTP response headers are used to stream large files using the RoadRunner. 4 | While the file is being streamed with the help of the RoadRunner, the PHP worker may be accepting the next request. 5 | 6 | Original issue: [link](https://github.com/roadrunner-server/roadrunner-plugins/issues/9) 7 | The middleware reads the file in 10MB chunks. For example, for the 5Gb file, only 10MB of RSS is used. If the file 8 | is smaller than 10MB, the middleware adjusts the buffer to fit the file size. 9 | 10 | ## Similar approaches: 11 | 12 | - [NGINX](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) 13 | - [Apache2](https://tn123.org/mod_xsendfile/) 14 | 15 | ## Configuration 16 | 17 | ```yaml 18 | version: "3" 19 | 20 | http: 21 | address: 127.0.0.1:55555 22 | max_request_size: 1024 23 | access_logs: false 24 | middleware: [ "sendfile" ] 25 | 26 | pool: 27 | num_workers: 2 28 | max_jobs: 0 29 | allocate_timeout: 60s 30 | destroy_timeout: 60s 31 | ``` 32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/en/http/static.md: -------------------------------------------------------------------------------- 1 | # HTTP — Serving static content 2 | 3 | `Static` HTTP middleware serving static content using RoadRunner on the main HTTP plugin endpoint. Using this middleware 4 | can slow down the overall performance by up to `~10%`, because RoadRunner has to check the path for each file request. 5 | 6 | > **INFO** 7 | > if there is no such file to serve, RR will redirect the request back to the PHP worker. 8 | 9 | ## Enable HTTP Middleware 10 | 11 | To enable static content serving use the configuration inside the http section: 12 | 13 | ```yaml 14 | version: "3" 15 | 16 | http: 17 | # host and port separated by semicolon 18 | address: 127.0.0.1:44933 19 | middleware: [ "static" ] # <-- Add static to the list of the middleware 20 | # Settings for "static" middleware (docs: https://roadrunner.dev/docs/http-http/2023.x/en). 21 | static: 22 | dir: "." 23 | forbid: [ "" ] 24 | calculate_etag: false 25 | weak: false 26 | allow: [ ".txt", ".php" ] 27 | request: 28 | input: "custom-header" 29 | response: 30 | output: "output-header" 31 | ``` 32 | 33 | Where: 34 | 35 | 1. `dir`: path to the directory. 36 | 2. `forbid`: file extensions that should not be served. 37 | 3. `allow`: extensions that should be served (empty - serve all except forbidden). If extension is present in both (allow and forbidden) hashmaps - that is treated as we should forbid file extension. 38 | 4. `calculate_etag`: enable etag calculation for the static file. 39 | 5. `weak`: use a weak generator (/W), it uses only filename to generate a CRC32 sum. If false - all file content used to generate CRC32 sum. 40 | 6. `request/response`: custom headers for the static files. 41 | 42 | To combine static content with other middleware, use the following sequence (static is always last in the line, then headers and gzip): 43 | 44 | ```yaml 45 | version: "3" 46 | 47 | http: 48 | # host and port separated by semicolon 49 | address: 127.0.0.1:44933 50 | middleware: [ "static", "headers", "gzip" ] 51 | # Settings for "headers" middleware (docs: https://roadrunner.dev/docs/http-http/2023.x/en). 52 | headers: 53 | cors: 54 | allowed_origin: "*" 55 | allowed_headers: "*" 56 | allowed_methods: "GET,POST,PUT,DELETE" 57 | allow_credentials: true 58 | exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma" 59 | max_age: 600 60 | # Settings for "static" middleware (docs: https://roadrunner.dev/docs/http-http/2023.x/en). 61 | static: 62 | dir: "." 63 | forbid: [ "" ] 64 | calculate_etag: false 65 | weak: false 66 | allow: [ ".txt", ".php" ] 67 | request: 68 | input: "custom-header" 69 | response: 70 | output: "output-header" 71 | ``` 72 | 73 | ## File server plugin 74 | 75 | Fileserver plugin serves the static files. It works similar to the `static` HTTP middleware and has extended functionality. 76 | Static HTTP middleware slows down request processing by `~10%` because RR has to check each request for the 77 | corresponding file. 78 | The file server plugin uses a different port and only serves static files. 79 | 80 | ## File server configuration 81 | 82 | ```yaml 83 | fileserver: 84 | # File server address 85 | # 86 | # Error on empty 87 | address: 127.0.0.1:10101 88 | # Etag calculation. Request body CRC32. 89 | # 90 | # Default: false 91 | calculate_etag: true 92 | 93 | # Weak etag calculation 94 | # 95 | # Default: false 96 | weak: false 97 | 98 | # Enable body streaming for files more than 4KB 99 | # 100 | # Default: false 101 | stream_request_body: true 102 | 103 | serve: 104 | # HTTP prefix 105 | # 106 | # Error on empty 107 | - prefix: "/foo" 108 | 109 | # Directory to serve 110 | # 111 | # Default: "." 112 | root: "../../../tests" 113 | 114 | # When set to true, the server tries minimizing CPU usage by caching compressed files 115 | # 116 | # Default: false 117 | compress: false 118 | 119 | # Expiration duration for inactive file handlers. Units: seconds. 120 | # 121 | # Default: 10, use a negative value to disable it. 122 | cache_duration: 10 123 | 124 | # The value for the Cache-Control HTTP-header. Units: seconds 125 | # 126 | # Default: 10 seconds 127 | max_age: 10 128 | 129 | # Enable range requests 130 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests 131 | # 132 | # Default: false 133 | bytes_range: true 134 | 135 | - prefix: "/foo/bar" 136 | root: "../../../tests" 137 | compress: false 138 | cache_duration: 10s 139 | max_age: 10 140 | bytes_range: true 141 | ``` 142 | -------------------------------------------------------------------------------- /docs/en/integration/cake.md: -------------------------------------------------------------------------------- 1 | # Integration — CakePHP 2 | 3 | > **Warning** 4 | > These set of integrations are currently available only for RoadRunner `v1.*`. 5 | 6 | | Repository | Status | 7 | |----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 8 | | https://github.com/CakeDC/cakephp-roadrunner | [![Downloads](https://poser.pugx.org/cakedc/cakephp-roadrunner/d/total.png)](https://packagist.org/packages/cakedc/cakephp-roadrunner) [![Latest Version](https://poser.pugx.org/cakedc/cakephp-roadrunner/v/stable.png)](https://packagist.org/packages/cakedc/cakephp-roadrunner) [![License](https://poser.pugx.org/cakedc/cakephp-roadrunner/license.svg)](https://packagist.org/packages/cakedc/cakephp-roadrunner) | -------------------------------------------------------------------------------- /docs/en/integration/chubbyphp.md: -------------------------------------------------------------------------------- 1 | # Integration — Chubbyphp Framework 2 | 3 | | Repository | Status | 4 | |------------------------------------------------------------------------------------------------------------------------|-------------| 5 | | [chubbyphp/chubbyphp-framework](https://github.com/chubbyphp/chubbyphp-framework/blob/master/doc/Server/Roadrunner.md) | MIT License | 6 | -------------------------------------------------------------------------------- /docs/en/integration/codeigniter.md: -------------------------------------------------------------------------------- 1 | # Integration — CodeIgniter 2 | 3 | | Repository | Status | 4 | |-----------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 5 | | [SDPM-lab/Codeigniter4-Roadrunner](https://github.com/SDPM-lab/Codeigniter4-Roadrunner) | [![Latest Stable Version](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/v)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) [![Total Downloads](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/downloads)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) [![License](https://poser.pugx.org/sdpmlab/codeigniter4-roadrunner/license)](//packagist.org/packages/sdpmlab/codeigniter4-roadrunner) | 6 | -------------------------------------------------------------------------------- /docs/en/integration/laravel.md: -------------------------------------------------------------------------------- 1 | # Integration — Laravel 2 | 3 | > **Note** 4 | > Laravel provides an official integration with RoadRunner via [Laravel Octane](https://github.com/laravel/octane). 5 | 6 | If you are looking for a more lightweight integration, you can consider the following packages: 7 | 8 | | Repository | Status | 9 | |---------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 10 | | [spiral/roadrunner-laravel](https://github.com/spiral/roadrunner-laravel) | ![Version](https://img.shields.io/packagist/php-v/spiral/roadrunner-laravel.svg) ![Build Status](https://img.shields.io/github/actions/workflow/status/spiral/roadrunner-laravel/tests.yml?branch=master&maxAge=30) ![Coverage](https://img.shields.io/codecov/c/github/spiral/roadrunner-laravel/master.svg) ![License](https://img.shields.io/packagist/l/spiral/roadrunner-laravel) | 11 | | [updg/roadrunner-laravel](https://github.com/UPDG/roadrunner-laravel) | ![License](https://img.shields.io/packagist/l/UPDG/roadrunner-laravel.svg) | 12 | | [hunternnm/laravel-roadrunner](https://github.com/Hunternnm/laravel-roadrunner) | ![License](https://img.shields.io/packagist/l/Hunternnm/laravel-roadrunner.svg) | 13 | 14 | > An example of a Laravel application in a Docker container with RoadRunner as a web server (plugged) 15 | > using [spiral/roadrunner-laravel](https://github.com/spiral/roadrunner-laravel) can be found 16 | > in [this repository](https://github.com/tarampampam/laravel-roadrunner-in-docker). 17 | -------------------------------------------------------------------------------- /docs/en/integration/mezzio.md: -------------------------------------------------------------------------------- 1 | # Integration — Mezzio 2 | 3 | | Repository | Status | 4 | |---------------------------------------------------------------------------------------------------|-------------| 5 | | [bcremer/roadrunner-mezzio-integration](https://github.com/bcremer/roadrunner-mezzio-integration) | MIT License | 6 | -------------------------------------------------------------------------------- /docs/en/integration/migration.md: -------------------------------------------------------------------------------- 1 | # Integration — Migration from v1.0 to v2.0 2 | 3 | To migration integration from RoadRunner v1.* to v2.* follow the next steps. 4 | 5 | ## Update Configuration 6 | 7 | Second version of RoadRunner use single worker factory for all of its plugins. This means that you must include a new 8 | section 9 | into your config `server` which is responsible for the worker creation. Limit service no longer presented as separate 10 | entity 11 | but rather part of specific service configuration. 12 | 13 | ```yaml 14 | rpc: 15 | listen: tcp://127.0.0.1:6001 16 | 17 | server: 18 | command: "php tests/psr-worker-bench.php" 19 | 20 | http: 21 | address: "0.0.0.0:8080" 22 | pool: 23 | num_workers: 4 24 | ``` 25 | 26 | > Read more in [config reference](../intro/config.md). 27 | 28 | ## No longer worry about echoing 29 | 30 | RoadRunner 2.0 intercepts all output to the STDOUT, this means you can start using default var_dump and other echo 31 | function 32 | without breaking the communication. Yay! 33 | 34 | ## Explicitly declare PSR-15 dependency 35 | 36 | We no longer ship the default PSR implementation with RoadRunner, make sure to include one you like the most by 37 | yourself. 38 | For example: 39 | 40 | ```bash 41 | $ composer require nyholm/psr7 42 | ``` 43 | 44 | ## Update Worker Code 45 | 46 | RoadRunner simplifies worker creation, use static `create()` method to automatically configure your worker: 47 | 48 | ```php 49 | waitRequest()) { 78 | try { 79 | $rsp = new Psr7\Response(); 80 | $rsp->getBody()->write('Hello world!'); 81 | 82 | $worker->respond($rsp); 83 | } catch (\Throwable $e) { 84 | $worker->getWorker()->error((string)$e); 85 | } 86 | } 87 | ``` 88 | 89 | ## Update RPCs 90 | 91 | To create RPC client use new Goridge API: 92 | 93 | ```php 94 | $rpc = \Spiral\Goridge\RPC\RPC::create('tcp://127.0.0.1:6001'); 95 | ``` -------------------------------------------------------------------------------- /docs/en/integration/phalcon.md: -------------------------------------------------------------------------------- 1 | # Integration — Phalcon 2 | 3 | ## Phalcon 3 4 | 5 | You can use [Phalcon+](https://github.com/bullsoft/phalconplus) to integrate with RR. Phalcon+ provides PSR-7 6 | converter-classes: 7 | 8 | - ```PhalconPlus\Http\NonPsrRequest``` to help converting PSR7 Request to Phalcon Native Request, 9 | - ```PhalconPlus\Http\PsrResponseFactory``` to help create PSR7 Response from Phalcon Native Response. 10 | 11 | and other finalizer to process stateful service in `di container`. 12 | 13 | ## Phalcon 4 14 | 15 | Phalcon 4 has builtin supports for PSR-7: 16 | 17 | - [Request](https://docs.phalcon.io/4.0/zh-cn/http-request), 18 | - [Response](https://docs.phalcon.io/4.0/zh-cn/http-response), 19 | 20 | you can easily integrate with RR. 21 | -------------------------------------------------------------------------------- /docs/en/integration/slim.md: -------------------------------------------------------------------------------- 1 | # Integration — Slim 2 | 3 | > **Warning** 4 | > These set of integrations are currently available only for RoadRunner `v1.*`. 5 | 6 | | Repository | Status | 7 | |-----------------------------------------------------------------------------|------------------| 8 | | https://github.com/n1215/roadrunner-docker-skeleton/blob/slimphp/worker.php | Not available | 9 | | https://github.com/roadrunner-server/roadrunner/issues/62 | Other references | 10 | 11 | -------------------------------------------------------------------------------- /docs/en/integration/spiral.md: -------------------------------------------------------------------------------- 1 | # Integration — Spiral Framework 2 | 3 | [Spiral Framework](https://spiral.dev) is a robust and powerful PHP framework developed by the R&D team 4 | at [Spiral Scout](https://spiralscout.com/). It is designed to facilitate the development and maintenance of medium to 5 | large-sized enterprise applications. 6 | 7 | Spiral prioritizes developer experience and offers an intuitive and user-friendly environment, akin to popular 8 | frameworks like Laravel and Symfony. **One of the core strengths of Spiral is its efficient memory management and 9 | prevention of memory leaks through advanced techniques.** 10 | 11 | RoadRunner is seamlessly integrated with Spiral to enhance the overall performance and scalability of applications. It 12 | enables the handling of various request types, including HTTP, gRPC, TCP, Websocket, Queue Job consuming, and Temporal 13 | via [spiral/roadrunner-bridge](hhttps://github.com/spiral/roadrunner-bridge) package. The integration unlocks a wide 14 | range of capabilities for building robust and high-performance applications. 15 | 16 | **Here is a list of features that are available:** 17 | 18 | - [HTTP](https://spiral.dev/docs/http-configuration) 19 | - [Static Content](https://spiral.dev/docs/advanced-storage#local-server) 20 | - [Queue](https://spiral.dev/docs/queue-roadrunner) (RabbitMQ, AWS SQS, Beanstalkd, In-Memory, Boltdb, Kafka, NATS) 21 | - [GRPC](https://spiral.dev/docs/grpc-configuration) 22 | - [TCP](https://github.com/spiral/roadrunner-bridge) 23 | - [Key-Value](https://spiral.dev/docs/basics-cache) 24 | - [Websocket](https://spiral.dev/docs/websockets-configuration) 25 | - [Metrics](https://spiral.dev/docs/advanced-prometheus-metrics) 26 | - [OpenTelemetry](https://spiral.dev/docs/advanced-telemetry) 27 | - [Logger](https://spiral.dev/docs/basics-logging#roadrunner-handler) -------------------------------------------------------------------------------- /docs/en/integration/symfony.md: -------------------------------------------------------------------------------- 1 | # Integration — Symfony Framework 2 | 3 | 4 | | Repository | Status | 5 | |----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 6 | | https://github.com/baldinof/roadrunner-bundle | [![Version][baldinof_badge_php_version]][baldinof_link_packagist] [![Build Status][baldinof_badge_build_status]][baldinof_link_build_status] [![License][baldinof_badge_license]][baldinof_link_license] | 7 | | https://github.com/php-runtime/roadrunner-symfony-nyholm | [![Version][phpruntime_badge_php_version]][phpruntime_link_packagist] [![License][phpruntime_badge_license]][phpruntime_link_license] | 8 | 9 | [baldinof_badge_packagist_version]:https://img.shields.io/packagist/v/baldinof/roadrunner-bundle.svg?maxAge=180 10 | [baldinof_badge_php_version]:https://img.shields.io/packagist/php-v/baldinof/roadrunner-bundle.svg?longCache=true 11 | 12 | [baldinof_badge_build_status]:https://img.shields.io/github/actions/workflow/status/baldinof/roadrunner-bundle/ci.yaml?branch=3.x 13 | 14 | [baldinof_badge_license]:https://img.shields.io/packagist/l/baldinof/roadrunner-bundle.svg?longCache=true 15 | 16 | [baldinof_link_packagist]:https://packagist.org/packages/baldinof/roadrunner-bundle 17 | 18 | [baldinof_link_build_status]:https://github.com/baldinof/roadrunner-bundle/actions 19 | 20 | [baldinof_link_license]:https://github.com/baldinof/roadrunner-bundle/blob/master/LICENSE 21 | 22 | [phpruntime_badge_packagist_version]:https://img.shields.io/packagist/v/runtime/roadrunner-symfony-nyholm.svg?maxAge=180 23 | 24 | [phpruntime_badge_php_version]:https://img.shields.io/packagist/php-v/symfony/runtime.svg?longCache=true 25 | 26 | [phpruntime_badge_license]:https://img.shields.io/packagist/l/runtime/roadrunner-symfony-nyholm.svg?longCache=true 27 | 28 | [phpruntime_link_packagist]:https://packagist.org/packages/runtime/roadrunner-symfony-nyholm 29 | 30 | [phpruntime_link_build_status]:https://github.com/php-runtime/runtime/actions 31 | 32 | [phpruntime_link_license]:https://github.com/php-runtime/roadrunner-symfony-nyholm/blob/master/LICENSE 33 | -------------------------------------------------------------------------------- /docs/en/integration/symlex.md: -------------------------------------------------------------------------------- 1 | # Integration — Symlex Framework 2 | 3 | > **Warning** 4 | > These set of integrations are currently available only for RoadRunner `v1.*`. 5 | 6 | [Symlex](https://symlex.org/) is a lean framework stack for agile Web development based on Symfony and Vuetify. 7 | RoadRunner is used as default application server since version 4.4.0. 8 | 9 | **The GitHub repository contains everything to get you started: [symlex/symlex](https://github.com/symlex/symlex)** 10 | 11 | Since its initial release in 2014, it has proven to be well suited for rapidly building microservices, CLI and 12 | single-page applications. It comes complete with working examples from testing to forms and database abstraction. 13 | 14 | > **Note** 15 | > As published by [phpbenchmarks.com](http://www.phpbenchmarks.com/en/benchmark/symlex/4.1), REST requests are more than 16 | > 40% faster compared to other common PHP frameworks. 17 | -------------------------------------------------------------------------------- /docs/en/integration/template.md: -------------------------------------------------------------------------------- 1 | # {INTEGRATION-NAME} 2 | List of available integrations. 3 | 4 | | Repository | Status | 5 | |------------|--------| 6 | -------------------------------------------------------------------------------- /docs/en/integration/ubiquity.md: -------------------------------------------------------------------------------- 1 | # Integration — Ubiquity Framework 2 | 3 | > **Warning** 4 | > These set of integrations are currently available only for RoadRunner `v1.*`. 5 | 6 | | Repository | Status | 7 | |--------------------------------------------------|---------------| 8 | | https://github.com/Lapinskas/roadrunner-ubiquity | Not available | -------------------------------------------------------------------------------- /docs/en/integration/yii.md: -------------------------------------------------------------------------------- 1 | # Integration — Yii 2 | 3 | ### Yii 2 4 | 5 | There is [Yii2 PSR-7 Bridge](https://github.com/charlesportwoodii/yii2-psr7-bridge) made by **Charles R. Portwood II** 6 | that covers almost everything needed for the integration. 7 | 8 | ### Yii 3 9 | 10 | There was 11 | an [experiment of running Yii3 with RoadRunner](https://forum.yiiframework.com/t/using-roadrunner-as-a-server/127060). 12 | There is also an [official application runner](https://github.com/yiisoft/yii-runner-roadrunner). 13 | -------------------------------------------------------------------------------- /docs/en/integration/zend.md: -------------------------------------------------------------------------------- 1 | # Integration — Zend Expressive 2 | 3 | > **Warning** 4 | > These set of integrations are currently available only for RoadRunner `v1.*`. 5 | 6 | | Repository | Status | 7 | |-------------------------------------------------------------------------|---------------| 8 | | https://github.com/sergey-telpuk/roadrunner-zend-expressive-integration | Not available | -------------------------------------------------------------------------------- /docs/en/intro/about.md: -------------------------------------------------------------------------------- 1 | # RoadRunner — What is it? 2 | 3 | RoadRunner is a high-performance PHP application server and process manager, designed with extensibility in mind through 4 | its utilization of plugins. Developed in Go, RoadRunner operates by running your application in the form of workers, 5 | where each worker represents an individual process, ensuring isolation and independence in their operation. 6 | 7 | It is designed to be like a central processor for PHP applications, helping developers create faster, more 8 | responsive and robust applications with ease. 9 | 10 | ![image](https://user-images.githubusercontent.com/773481/235296092-2f82643b-7822-4649-952a-0529efa3af88.png) 11 | 12 | ## Server 13 | 14 | RoadRunner efficiently manages a collection of PHP processes, referred to as workers, and routes incoming requests from 15 | various plugins to these workers. This communication is done through 16 | the [goridge](https://github.com/roadrunner-server/goridge) protocol, enabling your PHP application to handle requests 17 | and send responses back to clients. 18 | 19 | ![Base Diagram](https://user-images.githubusercontent.com/796136/65347341-79dd8600-dbe7-11e9-9621-1c5f2ef929e6.png) 20 | 21 | The following plugins are designed to run workers and handle specific types of requests: 22 | 23 | - [**HTTP**](../http/http.md) - Processes incoming HTTP requests from clients and forwards them to the PHP application. 24 | - [**Jobs**](../queues/overview.md) - Handles queued tasks received from queue brokers and sends them to a consumer PHP 25 | application for processing. 26 | - [**Centrifuge**](../plugins/centrifuge.md) - Manages events from Centrifugo WebSocket server clients and forwards them 27 | to the PHP application. It supports bidirectional communication, allowing for efficient and seamless interaction 28 | between the server and clients. 29 | - [**gRPC**](../plugins/grpc.md) - Deals with gRPC requests from clients and passes them on to the PHP application. 30 | - [**TCP**](../plugins/tcp.md) - Handles TCP requests from clients and routes them to the appropriate PHP application. 31 | - [**Temporal**](../workflow/temporal.md) - Manages workflows and activities, allowing for the efficient handling of 32 | various tasks and processes. 33 | 34 | By utilizing these plugins, RoadRunner ensures that your PHP application can effectively handle a wide range of requests 35 | and communication protocols, delivering optimal performance and flexibility. 36 | 37 | ## RPC 38 | 39 | RoadRunner also provides an RPC interface for communication between the application and the server, which plays a 40 | significant role in enhancing the interaction between the two components. This interface is particularly useful when 41 | working with the various plugins that support RPC communication, such as: 42 | 43 | - [**KV**](../kv/overview.md) - A cache service that allows for efficient storage and retrieval of cached data. 44 | - [**Locks**](../plugins/locks.md) - Offers a convenient means to manage distributed locks, ensuring resource access 45 | coordination across multiple processes or systems. 46 | - [**Service**](../plugins/service.md) - A dynamic server processes supervisor that enables seamless management of 47 | server processes directly from the application. 48 | - [**Jobs**](../queues/overview.md) - Provides the ability to dynamically manage queue pipelines from within the 49 | application, streamlining the execution of tasks and jobs. 50 | - [**Logger**](../lab/logger.md) - Facilitates the forwarding of logs from the application to the RoadRunner logger, 51 | ensuring centralized and efficient log management. 52 | - [**Metrics**](../lab/metrics.md) - Allows for the submission of application metrics to Prometheus, promoting 53 | comprehensive monitoring and analysis of application performance. 54 | 55 | ## PHP 56 | 57 | RoadRunner keeps PHP workers alive between incoming requests. This means that you can completely eliminate bootload time 58 | (such as framework initialization) and significantly speed up a heavy application. 59 | 60 | ![Base Diagram](https://user-images.githubusercontent.com/796136/65348057-00df2e00-dbe9-11e9-9173-f0bd4269c101.png) 61 | 62 | Since a worker resides in memory, all open resources persist across requests, remaining accessible for subsequent 63 | interactions. Utilizing the built-in [goridge](https://github.com/roadrunner-server/goridge), you can 64 | offload complex computations to the application server. For instance, you can schedule a background PHP job or 65 | even develop your own [custom RoadRunner plugin](../customization/plugin.md) to process complex tasks using Go, which 66 | offers improved efficiency and performance. By leveraging the strengths of both PHP and Go, you can create a more robust 67 | and high-performance solution for your applications. 68 | 69 | It is worth mentioning the following properties of the PHP workers: 70 | 71 | - **Isolation:** Each worker process operates independently, preventing interference with other worker processes and 72 | improving stability. 73 | - **Scalability:** The shared-nothing architecture makes it easier to scale applications by simply adding more worker 74 | processes. 75 | - **Fault Tolerance:** The failure of a single worker does not impact the functioning of other workers, ensuring 76 | uninterrupted service. 77 | - **Simplified Development:** By maintaining the isolation of workers, the shared-nothing architecture reduces the 78 | complexity of managing shared resources and simplifies the development process. 79 | 80 | ## What's Next? 81 | 82 | 1. [PHP Workers](../php/worker.md) - Learn how to configure and run PHP workers. 83 | 2. [PHP Workers — RPC to RoadRunner](../php/rpc.md) - Learn how to use RPC to communicate with PHP applications. 84 | 3. [Writing a custom plugin](../customization/plugin.md) - Learn how to create a custom plugin. -------------------------------------------------------------------------------- /docs/en/intro/config.md: -------------------------------------------------------------------------------- 1 | # RoadRunner — Configuration 2 | 3 | RoadRunner supports both **YAML** and **JSON** configuration formats. The examples in our documentation use YAML, but 4 | you can use JSON as well. 5 | 6 | > **Note** 7 | > To convert a YAML configuration file to JSON, you can use an online tool such 8 | > as https://onlineyamltools.com/convert-yaml-to-json. 9 | 10 | ## Configuration reference 11 | 12 | The most recent configuration reference with all available options can be found in the `.rr.yaml` file in the RoadRunner 13 | GitHub repository: 14 | 15 | - [**.rr.yaml**](https://github.com/roadrunner-server/roadrunner/blob/master/.rr.yaml) 16 | 17 | > **Warning** 18 | > We use dots as level separators, e.g.: `http.pool`, you can't use dots in section names, queue names, 19 | > etc. You can find out more about it [here](https://github.com/roadrunner-server/roadrunner/issues/1529). 20 | 21 | ## Configuration file 22 | 23 | The RoadRunner looks for a configuration file named `.rr.yaml` in the same directory as the server binary. 24 | 25 | If your configuration file and other application files are located in a different directory than the binary, you can use 26 | the `-w` option to specify the working directory. 27 | 28 | ```terminal 29 | ./rr serve -w /path/to/project 30 | ``` 31 | 32 | You can also use the `-c` option to specify the path to the configuration file if you don't want to specify the working 33 | directory. 34 | 35 | ```terminal 36 | ./rr serve -c /path/to/project/.rr-dev.yaml 37 | ``` 38 | 39 | Or you can combine the `-c` and `-w` options to specify both the configuration file and the working directory: 40 | 41 | ```terminal 42 | ./rr serve -c .rr-dev.yaml -w /path/to/project 43 | ``` 44 | 45 | > **Note** 46 | > Read more about starting the server in the [**Server Commands**](../app-server/cli.md) section. 47 | 48 | ## Environment variables 49 | 50 | Environment variables allow you to separate configuration data from your application code, making it more maintainable 51 | and portable. 52 | 53 | RoadRunner supports the expansion of environment variables using the `${VARIABLE}` or `$VARIABLE` syntax in a 54 | configuration file and CLI commands. You can use this feature to dynamically set values based on the current 55 | environment, such as database connection strings, API keys, and other sensitive information. 56 | 57 | You can specify a default value for an environment variable using the `${VARIABLE:-DEFAULT_VALUE}` syntax. For example, 58 | if you want to use a default value of `8080` for the `HTTP_PORT` environment variable if it is not defined or is empty, 59 | you can use the following configuration: 60 | 61 | ```yaml .rr.yaml 62 | http: 63 | address: 127.0.0.1:${HTTP_PORT:-8080} 64 | ``` 65 | 66 | > **Note** 67 | > You can find more information on Bash Environment Variable Defaults in 68 | > the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion). 69 | 70 | This allows you to easily customize the configuration based on your specific environment without changing the 71 | configuration file itself. 72 | 73 | Here's an example of a `docker-compose.yaml` file that redefines the `HTTP_PORT` for an RR service: 74 | 75 | ```yaml docker-compose.yaml 76 | version: '3.8' 77 | 78 | services: 79 | app: 80 | image: xxx 81 | environment: 82 | - HTTP_PORT=8081 83 | ... 84 | ``` 85 | 86 | ### Dotenv 87 | 88 | RoadRunner supports reading environment variables from `.env` files, which are typically used to store sensitive or 89 | environment-specific variables outside your codebase. 90 | 91 | To read environment variables from an `.env` file, you can use the `--dotenv` CLI option when starting RoadRunner. 92 | 93 | ```terminal 94 | ./rr serve --dotenv /var/www/config/.env 95 | ``` 96 | 97 | ### CLI Commands 98 | 99 | You can also use environment variables in CLI commands to customize the behavior of your RR server. This is especially 100 | useful when you need to pass configuration values that are environment-specific or sensitive, such as secrets or API 101 | keys. 102 | 103 | ```bash 104 | set -a 105 | source /var/www/config/.env 106 | set +a 107 | 108 | exec /var/www/rr \ 109 | -c /var/www/.rr.yaml \ 110 | -w /var/www \ 111 | -o http.pool.num_workers=${RR_NUM_WORKERS:-8} \ 112 | -o http.pool.max_jobs=${RR_MAX_JOBS:-16} \ 113 | -o http.pool.supervisor.max_worker_memory=${RR_MAX_WORKER_MEMORY:-512} 114 | serve 115 | ``` 116 | 117 | The `set -a` enables automatic exporting of variables. Any variables that are defined in `/var/www/config/.env` will be 118 | automatically exported to the environment, making them available to any child processes that are executed from the 119 | current shell. The final `set +a` command disables automatic exporting of variables, ensuring that only the variables 120 | that were defined in `/var/www/config/.env` are exported, and preventing any unintended variables from leaking into the 121 | environment. 122 | 123 | In this example, the following options are used: 124 | 125 | | Option | Description | 126 | |--------------------------|--------------------------------------------------------------------------------------------------------------------------------------| 127 | | **-c** | Specifies the configuration file. | 128 | | **-w** | Specifies the working directory. | 129 | | **-o** | Overwrites specific configuration options. | 130 | | **/var/www/config/.env** | File that contains the required environment variables. | 131 | | **${RR_NUM_WORKERS:-8}** | Sets the number of workers to `RR_NUM_WORKERS` from the `.env` file or uses the default value of `8` if the variable is not present. | 132 | 133 | ## What's Next? 134 | 135 | 1. [Server Commands](../app-server/cli.md) - learn how to start the server. 136 | 2. [Configuration plugin](../plugins/config.md) - learn more about the configuration plugin. 137 | 3. [PHP Workers — Environment configuration](../php/environment.md) - learn how to configure PHP workers environment. -------------------------------------------------------------------------------- /docs/en/intro/contributing.md: -------------------------------------------------------------------------------- 1 | # RoadRunner — Contributing 2 | 3 | Are you interested in helping out with RoadRunner? It's an open-source project that needs the help of developers like 4 | you to keep it running and make it even better. There are lots of ways you can get involved. 5 | 6 | ## Support Questions 7 | 8 | If you have any questions or need advice or suggestions, feel free to join 9 | our [Discord channel](https://discord.gg/spiralphp) for support from the RoadRunner maintainers and community members. 10 | 11 | 12 | 13 | ## Issues 14 | 15 | If you come across any issues or security vulnerabilities while using RoadRunner, please report them. The maintainers 16 | take these matters very seriously and will do their best to address them as soon as possible. You can report issues or 17 | vulnerabilities by [opening an issue](https://github.com/roadrunner-server/roadrunner/issues/new/choose) 18 | in `roadrunner-server/roadrunner` GitHub repository. 19 | 20 | ## Pull Requests 21 | 22 | One way to contribute to the RoadRunner is by submitting pull requests on GitHub. If you have a fix or improvement, you 23 | can submit a [pull request](https://github.com/roadrunner-server/roadrunner/pulls) and it will be reviewed by the 24 | maintainers. 25 | 26 | ## Commercial Support 27 | 28 | To further enhance the development and growth of the project, we have introduced 29 | the [RoadRunner Sponsors Program](https://github.com/sponsors/roadrunner-server). This initiative enables individuals, 30 | businesses, and organizations to contribute financially and help sustain our work, ensuring the continued success of the 31 | project. 32 | 33 | ### Why Sponsor RoadRunner? 34 | 35 | By sponsoring our project, you are directly supporting the development of new features, improvements to existing 36 | functionalities, and the overall stability and performance of the software. Your contributions will help us maintain a 37 | vibrant, innovative, and thriving community that benefits users across the globe. 38 | 39 | ### How to Become a Sponsor 40 | 41 | To become a RoadRunner sponsor, simply visit our [Sponsors Page](https://github.com/sponsors/roadrunner-server) and 42 | choose the sponsorship tier that best suits your preferences and level of commitment. Follow the provided instructions 43 | to complete the sponsorship process, and you'll be well on your way to supporting the continued success of the 44 | RoadRunner project. 45 | 46 | We are deeply grateful for the generosity of our sponsors and their commitment to the RoadRunner community. Together, we 47 | can continue to drive innovation and deliver outstanding solutions for users worldwide.** 48 | 49 | ## Contributors 50 | 51 | RoadRunner is an incredibly successful project thanks to the dedication and commitment of a global community that works 52 | tirelessly to improve, test, and refine its features. With a large and diverse group of active contributors from various 53 | parts of the world, the project has continued to evolve and deliver exceptional results. We would like to express our 54 | deepest gratitude to all those who have contributed their time, expertise, and passion to the project. 55 | 56 |
57 |
58 | 59 | 60 | ** -------------------------------------------------------------------------------- /docs/en/intro/features.md: -------------------------------------------------------------------------------- 1 | # RoadRunner — Features 2 | 3 | RoadRunner is a highly performant and flexible HTTP/HTTP2 server that is fully compatible 4 | with [PSR-7](https://www.php-fig.org/psr/psr-7/)/[PSR-17](https://www.php-fig.org/psr/psr-17/) standards. 5 | 6 | It is designed to replace traditional Nginx+FPM setups with enhanced performance and versatility. With its wide 7 | range of features, RoadRunner is a production-ready solution that is PCI DSS compliant, ensuring the security and safety 8 | of your web applications. 9 | 10 | **Here is a list of the features that make RoadRunner a great choice for your web application server:** 11 | 12 | - Production-ready 13 | - PCI DSS compliant (HTTP plugin) 14 | - PSR-7 HTTP server (file uploads, error handling, static files, hot reload, middleware, event listeners) 15 | - HTTPS and HTTP/2 support (including HTTP/2 Push, H2C) 16 | - A fully customizable http(s)/2 server 17 | - FastCGI support (HTTP plugin) 18 | - Flexible environment configuration 19 | - No external PHP dependencies (64bit version required) 20 | - Integrated metrics (Prometheus) 21 | - [Workflow engine](https://github.com/temporalio/sdk-php) by [Temporal.io](https://temporal.io) 22 | - Websockets support by [Centrifugo](https://centrifugal.dev/) websocket server 23 | - OpenTelemetry support 24 | - Works over TCP, UNIX sockets and process pipes 25 | - Automatic worker replacement, graceful and safe PHP process destruction 26 | - Worker create/allocate/destroy timeouts 27 | - Max requests per worker limitation 28 | - Worker lifecycle management (controller) 29 | - `max_memory` (graceful stop) 30 | - `ttl` (graceful stop) 31 | - `idle_ttl` (graceful stop) 32 | - `exec_tll` (brute, max_execution_time) 33 | - Protocol, worker and job level error management (including PHP errors) 34 | - Development Mode 35 | - Application server for [Spiral](https://github.com/spiral/framework) 36 | - Integration with popular PHP frameworks such as 37 | - [Symfony](https://github.com/php-runtime/roadrunner-symfony-nyholm), 38 | - [Laravel](https://github.com/laravel/octane), 39 | - Slim, 40 | - CakePHP 41 | - Compatible with both Windows and WSL2, with support for Unix sockets (`AF_UNIX`) on Windows 10/11. 42 | 43 | The list of features mentioned above is just the tip of the iceberg. RoadRunner is actively developed by maintainers 44 | and contributors, which means new features are constantly being added. 45 | 46 | If you have a feature request in mind, you can check 47 | out [GitHub issues](https://github.com/roadrunner-server/roadrunner/issues) page. Here you'll find a list of open 48 | feature requests. The RoadRunner community is active and responsive, so feel free to join the discussion on 49 | our [Discord channel](https://discord.gg/spiralphp) or [contribute](./contributing.md) to the project. 50 | 51 | 52 | 53 | With the support of the community, RoadRunner will continue to grow and evolve to meet the needs of modern web 54 | development. -------------------------------------------------------------------------------- /docs/en/intro/install.md: -------------------------------------------------------------------------------- 1 | # RoadRunner — Installation 2 | 3 | There are several ways to install RoadRunner, depending on your needs and preferences. 4 | 5 | ## Pre-built Binaries 6 | 7 | The simplest way to get the latest version of RoadRunner is to download one of the pre-built release binaries, which are 8 | available for various operating systems, including macOS, Linux, FreeBSD, and Windows. You can find these binaries on 9 | the GitHub [releases page](https://github.com/roadrunner-server/roadrunner/releases). 10 | 11 | To install RoadRunner, just download the appropriate archive from the releases page and extract it into your desired 12 | application directory. 13 | 14 | ## Docker 15 | 16 | If you prefer to use RoadRunner inside a Docker container, you can use the official RoadRunner Docker 17 | image `ghcr.io/roadrunner-server/roadrunner:latest`. 18 | 19 | > **Note** 20 | > More information about available tags can be 21 | > found [here](https://github.com/roadrunner-server/roadrunner/pkgs/container/roadrunner). 22 | 23 | **Here is an example of usage** 24 | 25 | ```dockerfile 26 | FROM ghcr.io/roadrunner-server/roadrunner:2023.X.X AS roadrunner 27 | FROM php:8.x-cli 28 | 29 | COPY --from=roadrunner /usr/bin/rr /usr/local/bin/rr 30 | 31 | # Install and configure your application 32 | # ... 33 | 34 | CMD rr serve -c .rr.yaml 35 | ``` 36 | 37 | > **Warning** 38 | > Don't forget to replace `2023.X.X` with a desired version of RoadRunner. 39 | 40 | ## Composer 41 | 42 | If you use Composer to manage your PHP dependencies, you can install the `spiral/roadrunner-cli` package to download the 43 | latest version of RoadRunner to your project's root directory. 44 | 45 | **Install the package** 46 | 47 | ```terminal 48 | composer require spiral/roadrunner-cli 49 | ``` 50 | 51 | Run the following command to download the latest version of RoadRunner 52 | 53 | ```terminal 54 | ./vendor/bin/rr get-binary 55 | ``` 56 | 57 | Server binary will be available at the root of your project. 58 | 59 | > **Warning** 60 | > PHP's extensions `php-curl` and `php-zip` are required to download RoadRunner automatically. 61 | > PHP's extensions `php-sockets` need to be installed to run roadrunner. 62 | > Check with `php --modules` your installed extensions. 63 | 64 | ## Debian Package 65 | 66 | For Debian-based operating systems such as **Ubuntu**, **Mint**, and **MX**, you can download the `.deb` package from 67 | the RoadRunner GitHub releases page and install it using dpkg. 68 | 69 | **Just run the following commands** 70 | 71 | ```bash 72 | wget https://github.com/roadrunner-server/roadrunner/releases/download/v2023.X.X/roadrunner-2023.X.X-linux-amd64.deb 73 | sudo dpkg -i roadrunner-2023.X.X-linux-amd64.deb 74 | ``` 75 | 76 | > **Warning** 77 | > Don't forget to replace `2023.X.X` with a desired version of RoadRunner. 78 | 79 | ## MacOS package using [Homebrew](https://brew.sh/): 80 | ```terminal 81 | brew install roadrunner 82 | ``` 83 | 84 | ## CURL 85 | 86 | You can also install RoadRunner using curl and the download-latest.sh script from the RoadRunner GitHub repository. 87 | 88 | **Just run the following commands** 89 | 90 | ```bash 91 | curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/roadrunner-server/roadrunner/master/download-latest.sh | sh 92 | ``` 93 | 94 | ## What's Next? 95 | 96 | After you have installed RoadRunner, you can proceed to the next steps and configure it for your needs. 97 | 98 | 1. [RoadRunner — Configuration](./config.md). 99 | 2. [Developer Mode](../php/developer.md). -------------------------------------------------------------------------------- /docs/en/known-issues/allocate-timeout.md: -------------------------------------------------------------------------------- 1 | # Allocate timeout error 2 | 3 | RoadRunner allocates workers like usual processes (via `fork` + `exec` syscalls). While RoadRunner is in the process of creating a worker (connecting to the pipes, TCP, etc.), some part of the worker might freeze the initial handshake. RoadRunner waits `pool.allocate_timeout` time for handshake to complete and return this error if `pool.allocate_timeout` exceeded. 4 | 5 | How to fix that? 6 | 7 | 1. Check the `pool.allocate_timeout` option. It should be in the form of `pool.allocate_timeout: 1s` or `pool.allocate_timeout: 1h`, so you should specify the units of measurement. Also, keep in mind, that `1s` for the allocate timeout might be a very small value, try to increase it. 8 | 2. `xdebug` might freeze the worker spawn while improperly configured. See this tutorial: [link](../php/debugging.md) 9 | 3. If you use a server's relay other than `pipes`, check this options: https://github.com/roadrunner-server/roadrunner/blob/master/.rr.yaml#L75. It's responsible for the initial handshake timeout between RR and PHP process established via `sockets` or `TCP`. 10 | -------------------------------------------------------------------------------- /docs/en/known-issues/stdout-crc.md: -------------------------------------------------------------------------------- 1 | # Invalid message sent to STDOUT 2 | 3 | This message `validation failed on the message sent to STDOUT, RR docs: https://roadrunner.dev/docs/known-issues-stdout-crc/2023.x/en, invalid message: ...` means that you or some application sent a non-correct message (raw) to the `STDOUT`. 4 | Process `STDOUT` is reserved for the RR communication with the PHP process via the `goridge` protocol (`v3`). 5 | 6 | How to fix that? 7 | 8 | 1. Check your application. All dependencies should send their messages to the `STDERR` instead of `STDOUT`. You may see the output after the `invalid message`. It might be shrunk on `windows`. 9 | 2. Check `dd` , `echo` inserted by you. PHP workers can redirect `echo` automatically from the `STDOUT` to `STDERR` but only after the worker is initialized fully. 10 | 3. Worker from the RRv1 was used. To update, see: [link](../integration/migration.md) 11 | 4. OPcache is enabled with JIT, but some extensions don't support it, which leads to the warnings. Tune the `error_reporting` configuration option (use only errors): [issue](https://github.com/roadrunner-server/roadrunner/issues/1306) 12 | 5. If you use a Symfony runtime, do not forget to add `APP_RUNTIME` to the server environment variables, as described here: https://github.com/php-runtime/roadrunner-symfony-nyholm. 13 | -------------------------------------------------------------------------------- /docs/en/kv/boltdb.md: -------------------------------------------------------------------------------- 1 | # KV Plugin — Boltdb Driver 2 | 3 | This type of driver is already supported by the RoadRunner and does not require any additional installations. 4 | 5 | ## Configuration 6 | 7 | The complete boltdb driver configuration: 8 | 9 | ```yaml 10 | version: "3" 11 | 12 | kv: 13 | # User defined name of the storage. 14 | boltdb: 15 | # Required section. 16 | # Should be "boltdb" for the boltdb driver. 17 | driver: boltdb 18 | 19 | config: 20 | # Optional section. 21 | # Default: "rr.db" 22 | file: "./rr.db" 23 | 24 | # Optional section. 25 | # Default: 0777 26 | permissions: 0777 27 | 28 | # Optional section. 29 | # Default: "rr" 30 | bucket: "rr" 31 | 32 | # Optional section. 33 | # Default: 60 34 | interval: 60 35 | ``` 36 | 37 | ## Options 38 | 39 | Below is a more detailed description of the various boltdb options.: 40 | 41 | ### File 42 | 43 | `file`: Database file path name. In the case that such a file does not exist, RoadRunner will create this file on its 44 | own at startup. Note that this must be an existing directory, otherwise a "The system cannot find the path specified" 45 | error will occur, indicating that the full database pathname is invalid. Might be a full path with 46 | file: `/foo/bar/rr1.db`. Default: `rr.db`. 47 | 48 | ### Permissions 49 | 50 | `permissions`: The file permissions in UNIX format of the database file, set at the time of its creation. If the file 51 | already exists, the permissions will not be changed. 52 | 53 | ### Bucket 54 | 55 | `bucket`: The bucket name. You can create several boltdb connections by specifying different buckets and in this case 56 | the data stored in one bucket will 57 | not intersect with the data stored in the other, even if the database file and other settings are completely 58 | identical. 59 | 60 | ### Interval 61 | 62 | `interval`: The interval (in seconds) between checks for the lifetime of the 63 | value in the cache. The meaning and behavior is similar to that used in the 64 | case of the memory driver. 65 | -------------------------------------------------------------------------------- /docs/en/kv/memcached.md: -------------------------------------------------------------------------------- 1 | # KV Plugin — Memcached Driver 2 | 3 | Before configuring the Memcached driver, please make sure that the Memcached Server is installed and running. You can 4 | read more about this [in the documentation](https://memcached.org/). 5 | 6 | ## Configuration 7 | 8 | The complete memcached driver configuration: 9 | 10 | ```yaml 11 | version: "3" 12 | 13 | kv: 14 | # User defined name of the storage. 15 | memcached: 16 | # Required section. 17 | # Should be "memcached" for the memcached driver. 18 | driver: memcached 19 | config: 20 | # Optional section. 21 | # Default: "127.0.0.1:11211" 22 | addr: "127.0.0.1:11211" 23 | ``` 24 | 25 | ## Options 26 | 27 | Below is a more detailed description of each of the memcached-specific options: 28 | 29 | ### Addr 30 | 31 | `addr`: String of memcached connection in format "`[HOST]:[PORT]`". 32 | 33 | In the case that there are several memcached servers, then the list of connections can be listed in an array format, for 34 | example: 35 | 36 | ```yaml 37 | version: "3" 38 | 39 | kv: 40 | memcached: 41 | driver: memcached 42 | config: 43 | addr: [ "127.0.0.1:11211", "127.0.0.1:11222" ] 44 | ``` -------------------------------------------------------------------------------- /docs/en/kv/memory.md: -------------------------------------------------------------------------------- 1 | # KV Plugin — Memory Driver 2 | 3 | This type of driver is already supported by the RoadRunner and does not require any additional installations. 4 | 5 | > **Warning** 6 | > This type of storage, all data is contained in memory and will be destroyed when the RoadRunner Server is restarted. 7 | > If you need persistent storage without additional dependencies, then it is recommended to use the boltdb driver. 8 | 9 | ## Configuration 10 | 11 | The complete memory driver configuration: 12 | 13 | ```yaml 14 | version: "3" 15 | 16 | kv: 17 | # User defined name of the storage. 18 | memory: 19 | # Required section. 20 | # Should be "memory" for the memory driver. 21 | driver: memory 22 | config: {} 23 | ``` 24 | 25 | There are no additional configuration options for this driver. The `in-memory` driver will automatically create callbacks for items with TTL. -------------------------------------------------------------------------------- /docs/en/lab/access-logs.md: -------------------------------------------------------------------------------- 1 | # Logging — HTTP Access logs 2 | 3 | RoadRunner has the HTTP access logs support, which provides detailed information about incoming HTTP requests and 4 | responses. 5 | 6 | > **Note** 7 | > This feature is disabled by default, but it can be easily enabled by configuring the HTTP server. 8 | 9 | ## Enabling HTTP Access Logs 10 | 11 | To enable HTTP access logs in RoadRunner, you need to modify the configuration file of the HTTP server. 12 | 13 | **Here's an example configuration file:** 14 | 15 | ```yaml .rr.yaml 16 | version: "3" 17 | 18 | http: 19 | address: 127.0.0.1:8000 20 | access_logs: true 21 | # ... 22 | ``` 23 | 24 | Once enabled, RoadRunner will log the following information for each incoming HTTP request: 25 | 26 | - `method` - HTTP method of the request 27 | - `remote_addr` - Remote address of the client 28 | - `bytes_sent` - Content length of the response 29 | - `http_host` - Host name of the server 30 | - `request` - Query string of the request 31 | - `time_local` - Local time of the server in Common Log Format 32 | - `request_length` - Request body size including headers in bytes (content-len + size of all headers) in bytes. Max allowed headers 33 | size for the RR is 1MB. 34 | - `request_time` - Request processing time in seconds with a milliseconds' resolution 35 | - `status` - HTTP response status 36 | - `http_user_agent` - HTTP user [agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) string of the client 37 | - `http_referer` - HTTP [referer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) string of the client 38 | -------------------------------------------------------------------------------- /docs/en/lab/applogger.md: -------------------------------------------------------------------------------- 1 | # Logging — Application logger 2 | 3 | The RoadRunner server has a useful `app-logger` plugin that allows users to send logs from their applications to the 4 | RoadRunner server using an RPC interface. This plugin is enabled by default and does not require any additional 5 | configurations. It can be used to observe all application and server logs in one place. This is especially useful when 6 | debugging and monitoring applications. 7 | 8 | > **Note** 9 | > It will send raw messages to the RoadRunner `STDERR` 10 | 11 | ## Configuration 12 | 13 | The `logs` section in the RoadRunner configuration file allows you to configure logging behavior for their application. 14 | 15 | ```yaml .rr.yaml 16 | rpc: 17 | listen: tcp://127.0.0.1:6001 18 | 19 | logs: 20 | channels: 21 | app: 22 | level: info 23 | ``` 24 | 25 | > **Warning** 26 | > To interact with the RoadRunner app-logger plugin, you will need to have the RPC defined in the rpc configuration 27 | > section. You can refer to the documentation page [here](../php/rpc.md) to learn more about the configuration. 28 | 29 | The `level` key is used to specify the logging level for this channel. This means that only log messages with a severity 30 | level of info or higher will be sent to this channel. 31 | 32 | > **Note** 33 | > Read more about logging in the [Logging — Logger](./logger.md) section. 34 | 35 | ## PHP client 36 | 37 | The RoadRunner `app-logger` plugin comes with a convenient PHP package that simplifies the process of integrating the 38 | plugin with your PHP application. 39 | 40 | ### Installation 41 | 42 | To get started, you can install the package via Composer using the following command: 43 | 44 | ```terminal 45 | composer require roadrunner-php/app-logger 46 | ``` 47 | 48 | ### Usage 49 | 50 | After the installation, you can create an instance of the `RoadRunner\Logger\Logger` class, which will allow you to use 51 | the available class methods. 52 | 53 | **Here is an example:** 54 | 55 | ```php 56 | use Spiral\Goridge\RPC\RPC; 57 | use RoadRunner\Logger\Logger; 58 | 59 | $rpc = RPC::create('tcp://127.0.0.1:6001'); 60 | 61 | $logger = new Logger($rpc); 62 | 63 | $logger->info('Hello, RoadRunner!'); 64 | $logger->warning('Something might be wrong...'); 65 | $logger->error('Houston, we have a problem!'); 66 | ``` 67 | 68 | > **Note** 69 | > You can refer to the documentation page [here](../php/rpc.md) to learn more about creating the RPC connection. 70 | 71 | ### Available methods 72 | 73 | - `debug(string): void`: Sends a debug log message to the server 74 | - `error(string): void`: Sends an error log message to the server 75 | - `info(string): void`: Sends an info log message to the server 76 | - `warning(string): void`: Sends a warning log message to the server 77 | - `log(string): void`: Sends a log message directly to the `STDERR` of the server 78 | 79 | ## API 80 | 81 | ### RPC API 82 | 83 | RoadRunner provides an RPC API, which allows you to manage app-logger in your applications using remote 84 | procedure calls. The RPC API provides a set of methods that map to the available methods of 85 | the `RoadRunner\Logger\Logger`class in PHP. 86 | 87 | > **Note** 88 | > All methods accept a `string` (which will be log message) as a first argument and a `bool` placeholder for the second 89 | > arg. 90 | 91 | #### Error 92 | 93 | Method sends an `error` log message with the specified message to the RoadRunner server. 94 | 95 | ```go 96 | func (r *RPC) Error(in string, _ *bool) error {} 97 | ``` 98 | 99 | #### Info 100 | 101 | Method sends an `info` log message with the specified message to the RoadRunner server. 102 | 103 | ```go 104 | func (r *RPC) Info(in string, _ *bool) error {} 105 | ``` 106 | 107 | #### Warning 108 | 109 | Method sends a `warning` log message with the specified message to the RoadRunner server. 110 | 111 | ```go 112 | func (r *RPC) Warning(in string, _ *bool) error {} 113 | ``` 114 | 115 | #### Debug 116 | 117 | Method sends a `debug` log message with the specified message to the RoadRunner server. 118 | 119 | ```go 120 | func (r *RPC) Debug(in string, _ *bool) error {} 121 | ``` 122 | 123 | #### Log 124 | 125 | Method sends a log message with the specified message directly to the `STDERR` of the RoadRunner server. 126 | 127 | ```go 128 | func (r *RPC) Log(in string, _ *bool) error {} 129 | ``` -------------------------------------------------------------------------------- /docs/en/lab/dashboards/dashboards.md: -------------------------------------------------------------------------------- 1 | # RoadRunner Dashboards 2 | 3 | Grafana's dashboards for the RR (including temporal) installations. More info about the available metrics is here: [link](../metrics.md) 4 | 5 | ## gRPC dashboard 6 | 7 | This dashboard contains gRPC plugin metrics: [link](grpc.md) 8 | 9 | ## HTTP dashboard 10 | 11 | This dashboard contains http plugin metrics: [link](http.md) 12 | 13 | ## JOBS dashboard 14 | 15 | This dashboard contains jobs plugin metrics: [link](jobs.md) 16 | 17 | ## Temporal dashboard 18 | 19 | [This](temporal.md) dashboard contains temporal (RR part) plugin metrics. 20 | Official repo with the temporal metrics available here: https://github.com/temporalio/dashboards 21 | -------------------------------------------------------------------------------- /docs/en/lab/health.md: -------------------------------------------------------------------------------- 1 | # Observability — Health and Readiness checks 2 | 3 | The RoadRunner Status Plugin provides a healthcheck status for various plugins such 4 | as `http`, `grpc`, `temporal`, `jobs` and `centrifuge`. This plugin provides an easy way to check the condition of the 5 | workers and ensure that they are ready to serve requests. 6 | 7 | ## Activation of the Status Plugin 8 | 9 | To activate the health/readiness checks endpoint, include a `status` section in your configuration file. 10 | 11 | Here is an example: 12 | 13 | ```yaml .rr.yaml 14 | version: "3" 15 | 16 | status: 17 | address: 127.0.0.1:2114 18 | ``` 19 | 20 | The above configuration sets the address to `127.0.0.1:2114`. This is the address that the plugin will listen to. You 21 | can change the address to any IP address and port number of your choice. 22 | 23 | To access the health check, you need to use the following URL: http://127.0.0.1:2114/health?plugin=http. This URL will 24 | return the health status of the http plugin. 25 | 26 | > **Note** 27 | > You can specify multiple plugins by separating them with a comma. For example, to check the health status of both the 28 | > http and grpc plugins, you can use the following URL: http://127.0.0.1:2114/health?plugin=http&plugin=grpc. 29 | 30 | The health check endpoint will return `HTTP 200` if there is at least one worker ready to serve requests. If there are 31 | no workers ready to service requests, the endpoint will return `HTTP 500`. If there are any other errors, the endpoint 32 | will also return `HTTP 500`. 33 | 34 | The readiness check endpoint will return `HTTP 200` if there is at least one worker ready to take the request (i.e., not 35 | currently busy with another request). If there is no worker ready or all workers are busy, the endpoint will return 36 | `HTTP 500` status code (you can override this too). 37 | 38 | ## Customizing the Not-Ready Status Code 39 | 40 | By default, Status Plugin uses a `500` status code. However, you can replace this status code with a custom one. 41 | 42 | To achieve this, utilize the `unavailable_status_code` option: 43 | 44 | ```yaml .rr.yaml 45 | version: "3" 46 | 47 | status: 48 | address: 127.0.0.1:2114 49 | unavailable_status_code: 501 50 | ``` 51 | 52 | ## Jobs plugin pipelines check 53 | 54 | In addition to checking the health status of the workers, you can also examine the pipelines in the Jobs plugin using 55 | the following URL: http://127.0.0.1:2114/jobs 56 | 57 | This URL will return the status of the pipelines in the Jobs plugin. The output will be in the following format: 58 | 59 | ``` 60 | plugin: jobs: pipeline: test-1 | priority: 13 | ready: true | queue: test-1 | active: 0 | delayed: 0 | reserved: 0 | driver: memory | error: 61 | ``` 62 | 63 | ## Use cases 64 | 65 | The health check endpoint serves the following purposes: 66 | 67 | ### Kubernetes Readiness and Liveness Probes 68 | 69 | In Kubernetes, you can use readiness and liveness probes to check the health of your application. It can be used as a 70 | readiness or liveness probe to ensure that your application is ready to serve requests. You can configure Kubernetes to 71 | check the health check endpoint and take appropriate action if the endpoint returns an error. 72 | 73 | **Read more [here](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)** 74 | 75 | ### AWS Target Group Health Checks 76 | 77 | If you are using AWS Elastic Load Balancer, you can use it as a health check for your target group. You can configure 78 | the target group to check the health check endpoint and take appropriate action if the endpoint returns an error. 79 | 80 | **Read more [here](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html)** 81 | 82 | ### GCE Load Balancing Health Checks 83 | 84 | If you are using Google Cloud Platform, you can use it as a health check for your load balancer. You can configure the 85 | load balancer to check the health check endpoint and take appropriate action if the endpoint returns an error. 86 | 87 | **Read more [here](https://cloud.google.com/load-balancing/docs/health-checks)** 88 | -------------------------------------------------------------------------------- /docs/en/lab/logger.md: -------------------------------------------------------------------------------- 1 | # Logging — Logger 2 | 3 | Logger Plugin is responsible for collecting logs from server plugins and PHP application workers' `STDERR` and 4 | displaying them in the RoadRunner `STDERR`/`STDOUT`. It comes with a variety of options that allow you to customize the 5 | way your application logs are collected and displayed. 6 | 7 | ### Configuration 8 | 9 | ### Modes 10 | 11 | ```yaml 12 | logs: 13 | mode: production 14 | ``` 15 | 16 | There are three available modes: 17 | 18 | 1. `production` - This mode uses logger settings that are optimized for production usage. 19 | 2. `development` - This mode is enabled by default and is designed for use during application development. In 20 | development mode, DPanicLevel logs panic, console colors are used, and logs are written to standard error. Sampling 21 | is disabled, and stack traces are automatically included on logs of WarnLevel and above. 22 | 3. `raw` - This mode displays messages as raw output without any formatting. This mode is useful in production 23 | environments where you need to parse logs programmatically. 24 | 25 | > **Note** 26 | > Use `production` mode in production environments. It is optimized for production usage. 27 | 28 | ### Encoding 29 | 30 | Logger supports two types of encoding, `console` and `json`. By default, `console` encoding is used, which outputs logs 31 | in a friendly format. JSON encoding, on the other hand, returns messages in a JSON Structured logging format. This 32 | format presents log messages as JSON objects with key-value pairs representing each log message field, making them more 33 | machine-readable and easier to process programmatically. JSON encoding is also better suited for production usage. 34 | 35 | ```yaml 36 | logs: 37 | encoding: console 38 | ``` 39 | 40 | ### Level 41 | 42 | The level is used to specify the logging level. This means that only log messages with a severity level will be sent to 43 | this channel. Available levels include `panic`, `error`, `warn`, `info`, and `debug`. 44 | 45 | ```yaml 46 | logs: 47 | level: info 48 | ``` 49 | 50 | > **Note** 51 | > The default level is `debug`. 52 | 53 | ### Output 54 | 55 | By default, RoadRunner sends logs to `STDERR`. However, you can configure RoadRunner to send logs to `STDOUT` by using 56 | the output key. 57 | 58 | ```yaml 59 | logs: 60 | output: stdout 61 | ``` 62 | 63 | ### Line Endings 64 | 65 | It allows configuring custom line endings for the logger. By default, the plugin uses `\n` as the line ending. Note that the `\n` is a forced default. This means that if the value is empty, RoadRunner will still use `\n`. So no empty line endings are allowed. 66 | 67 | ```yaml 68 | logs: 69 | line_ending: "\r\n" 70 | ``` 71 | 72 | ### Channels 73 | 74 | In addition, you can configure each plugin log messages individually using the `channels` section. It allows you to 75 | customize the logger settings for each plugin independently. You can disable logging for a particular plugin or change 76 | its log mode and output destination. 77 | 78 | ```yaml 79 | version: "3" 80 | 81 | logs: 82 | encoding: console # default value 83 | level: info 84 | mode: none # disable server logging. Also `off` can be used. 85 | channels: 86 | http: 87 | mode: production 88 | output: http.log 89 | ``` 90 | 91 | ## File Logger 92 | 93 | It is possible to redirect channels or the entire log output to a file. To use the file logger, you need to set 94 | the `file_logger_options.log_output` option to the filename where you want to write the logs. 95 | 96 | ### Entire log 97 | 98 | ```yaml 99 | logs: 100 | mode: development 101 | file_logger_options: 102 | log_output: "test.log" 103 | max_size: 10 104 | max_age: 24 105 | max_backups: 10 106 | compress: true 107 | ``` 108 | 109 | ### Channel 110 | 111 | You can also redirect a specific channel to a file. To do this, you need to specify the channel name in the `channels` 112 | 113 | ```yaml 114 | logs: 115 | mode: development 116 | level: debug 117 | channels: 118 | http: 119 | file_logger_options: 120 | log_output: "test.log" 121 | max_size: 10 122 | max_age: 24 123 | max_backups: 10 124 | compress: true 125 | ``` 126 | 127 | ### Available options 128 | 129 | 1. `log_output`: Filename is the file to write logs to in the same directory. It uses `processname-lumberjack.log` in 130 | `os.TempDir()` if empty. 131 | 2. `max_size`: is the maximum size in megabytes of the log file before it gets rotated. It defaults to 100 megabytes. 132 | 3. `max_age`: is the maximum number of days to retain old log files based on the timestamp encoded in their filename. 133 | Note that a day is defined as 24 hours and may not exactly correspond to calendar days due to daylight savings, leap 134 | seconds, etc. The default is not to remove old log files based on age. 135 | 4. `max_backups`: is the maximum number of old log files to retain. The default is to retain all old log files (though 136 | MaxAge may still cause them to get deleted.) 137 | 5. `compress`: determines if the rotated log files should be compressed using gzip. The default is not to perform 138 | compression. 139 | 6. `log_ending`: line ending to use in the logger. Default is new line - `\n`. 140 | 141 | ## ZapLogger 142 | 143 | Feel free to register your own [ZapLogger](https://github.com/uber-go/zap) extensions. 144 | -------------------------------------------------------------------------------- /docs/en/license.md: -------------------------------------------------------------------------------- 1 | # LICENSE 2 | 3 | MIT License 4 | 5 | Copyright (c) 2023 SpiralScout 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /docs/en/php/debugging.md: -------------------------------------------------------------------------------- 1 | # PHP Workers — Debugging 2 | 3 | You can use RoadRunner scripts with xDebug extension. In order to enable configure your IDE to accept remote connections. 4 | 5 | > **Note:** 6 | > If you run multiple PHP processes you have to extend the maximum number of allowed connections to the number of 7 | > active workers, otherwise some calls would not be caught on your breakpoints. 8 | 9 | ![xdebug](https://user-images.githubusercontent.com/796136/46493729-c767b400-c819-11e8-9110-505a256994b0.png) 10 | 11 | To activate xDebug make sure to set the `xdebug.mode=debug` in your `php.ini`. 12 | 13 | To enable xDebug in your application make sure to set ENV variable `XDEBUG_SESSION`: 14 | 15 | ```yaml .rr.yaml 16 | rpc: 17 | listen: tcp://127.0.0.1:6001 18 | 19 | server: 20 | command: "php worker.php" 21 | env: 22 | - XDEBUG_SESSION: 1 23 | 24 | http: 25 | address: "0.0.0.0:8080" 26 | pool: 27 | num_workers: 1 28 | debug: true 29 | ``` 30 | 31 | Please, keep in mind this guide: [xdebug3](https://xdebug.org/docs/upgrade_guide). 32 | 33 | You should be able to use breakpoints and view state at this point. 34 | 35 | ## PhpStorm notes 36 | 37 | ```bash 38 | export PHP_IDE_CONFIG="serverName=octane-app.test" 39 | export XDEBUG_SESSION="mode=debug start_with_request=yes client_host=127.0.0.1 client_port=9003 idekey=PHPSTORM" 40 | 41 | php -dvariables_order=EGPCS artisan octane:start --max-requests=250 --server=roadrunner --port=8000 --rpc-port=6001 --watch --workers=1 42 | ``` 43 | 44 | Feel free to check our community notes: [link](https://forum.spiral.dev/t/xdebug-integration/86/1) 45 | 46 | ## Jobs debugging 47 | 48 | ### Prerequisites 49 | 50 | 1. XDebug 3 installed and properly configured. 51 | 2. Number of jobs workers set to `1` with `jobs.pool.num_workers` configuration option in `.rr.yaml`. 52 | 53 | ### Debug process 54 | 55 | If you have any active XDebug listener while starting RoadRunner with XDebug enabled — disable it. This will prevent 56 | false-positive debug session. 57 | 58 | Once RoadRunner starts all workers, enable XDebug listener and reset jobs workers with: 59 | 60 | ```terminal 61 | ./rr reset jobs 62 | ``` 63 | 64 | Now you should see debug session started: 65 | 66 | 1. Step over to some place where job task is being resolved with `$consumer->waitTask()`. 67 | 2. As soon as you reach it, debugger stops but session will still be active. 68 | 3. Trigger task consumption with either an HTTP request or a console command (depending on how your application works). 69 | and continue to debug job worker as usual within active session started before. 70 | 4. You can continue to debug jobs as long as debug session active. 71 | 72 | If connections session broken or timed out, you can repeat instruction above to reestablish connection by resetting jobs workers. 73 | -------------------------------------------------------------------------------- /docs/en/php/developer.md: -------------------------------------------------------------------------------- 1 | # PHP Workers — Developer Mode 2 | 3 | When RoadRunner starts workers, they operate in daemon mode. In this mode, you need to reload the server every time you 4 | make changes to your codebase. 5 | 6 | ## Manual restarting 7 | 8 | One of the way reloading server is using console command: 9 | 10 | ```terminal 11 | ./rr reset 12 | ``` 13 | 14 | This command is also helpful when you need to restart a remote RoadRunner server using a local RoadRunner 15 | client. 16 | 17 | ### Restarting in Docker container 18 | 19 | For example, you can use this command to restart workers inside a Docker container. To do this, you need to 20 | configure the RoadRunner server to handle external RPC requests by adding the following lines to your configuration 21 | file: 22 | 23 | ```yaml .rr.yaml 24 | rpc: 25 | listen: tcp://:6001 26 | ``` 27 | 28 | > **Note** 29 | > You must also forward/expose port `6001` in your Docker container to be able to use this feature. 30 | 31 | Now when you run the command, RoadRunner client sends RPC request to the running server. 32 | 33 | > **Warning** 34 | > Pay attention to the RPC host and port which uses RoadRunner client specified in the `.rr.yaml` should be the same as 35 | > the RPC host and port which uses RoadRunner server. By default, client uses `127.0.0.1:6001`. 36 | 37 | ## Debug Mode 38 | 39 | It can be a time-consuming and tedious process to restart workers manually, especially during the development phase 40 | of a project. To address this issue, RoadRunner provides a debug mode that automatically restarts workers after each 41 | handled request, allowing developers to make changes to their codebase without having to manually reload the server each 42 | time. 43 | 44 | To enable debug mode, you can set the `pool.debug` option to `true` in desired plugin section that has workers pool: 45 | 46 | ```yaml 47 | http: 48 | pool: 49 | debug: true 50 | num_workers: 4 51 | ``` 52 | 53 | Or if you have only `debug` option in the `pool` section you can use short syntax: 54 | 55 | ```yaml 56 | http: 57 | pool.debug: true 58 | ``` 59 | 60 | > **Note** 61 | > Every plugin in RoadRunner that creates workers has a `pool` section in which you can activate debug mode. 62 | 63 | 64 | > **Warning** 65 | > When using the `pool.debug` option in RoadRunner, it is important to note that settings in `pool` section would work 66 | > differently. All options will be ignored (`supervisor`, `max_jobs`, `num_workers`, etc). This is because, in debug 67 | > mode, RoadRunner does not create a worker at startup. Instead, it waits for requests to come in and creates workers 68 | > accordingly. After the response, RoadRunner stops and removes the worker. 69 | > When you send 2-3-n parallel requests to RoadRunner, it creates 2-3-n workers to handle those requests simultaneously. 70 | > The number of workers depends on the number of requests you send. Similarly, when you use the Jobs plugin and the Jobs 71 | > consumers, every message consumed creates a worker to handle that message. The number of workers is based on the 72 | > number of messages consumed. 73 | > 74 | > This enables you to make changes to your codebase and reload it automatically. 75 | 76 | ## Stop Command 77 | 78 | In RoadRunner, you can send a `stop` command from the worker to the parent server to force process destruction. When 79 | this happens, the job/request will be automatically forwarded to the next worker in the queue. 80 | 81 | You can use this feature to implement `max_jobs` control on the PHP side. This can be useful for controlling memory 82 | usage inside the PHP script or for managing long-running tasks that need to be periodically restarted. 83 | 84 | ```php 85 | waitRequest()) { 99 | try { 100 | $rsp = new Psr7\Response(); 101 | $rsp->getBody()->write('Hello world!'); 102 | 103 | $count++; 104 | if ($count > 10) { 105 | $worker->getWorker()->stop(); 106 | return; 107 | } 108 | 109 | $worker->respond($rsp); 110 | } catch (\Throwable $e) { 111 | $worker->getWorker()->error((string)$e); 112 | } 113 | } 114 | ``` 115 | 116 | As you can see in the example above, we send a `stop` command after handling 10 requests, to force process destruction. 117 | This ensures that the script does not consume too much memory and avoids any potential memory leaks. 118 | -------------------------------------------------------------------------------- /docs/en/php/environment.md: -------------------------------------------------------------------------------- 1 | # PHP Workers — Environment configuration 2 | 3 | RoadRunner offers the capability to set and manage environment variables for workers. This capability allows you to set 4 | specific environment variables when workers are initialized, providing a flexible and organized method for managing 5 | application configurations. 6 | 7 | ## Setting Env Variables 8 | 9 | You can set environment variables for PHP workers by defining them in the `server.env` section of the RoadRunner 10 | configuration file. These variables will be applied to all workers when they are started by the server. 11 | 12 | **Here's an example:** 13 | 14 | ```yaml .rr.yaml 15 | server: 16 | command: "php worker.php" 17 | env: 18 | DEBUG: true 19 | ``` 20 | 21 | In this example, when RoadRunner starts a PHP worker, it will set the `DEBUG` environment variable to `true`. 22 | 23 | > **Warning** 24 | > All environment variable keys will be automatically converted to uppercase. 25 | 26 | ## Default Env Values in PHP Workers 27 | 28 | RoadRunner comes with a set of default environment (ENV) values that facilitate proper communication between the PHP 29 | process and the server. These values are automatically available to workers and can be used to configure and manage 30 | various aspects of the worker's operation. 31 | 32 | **Here's a list of the default ENV values provided by RoadRunner:** 33 | 34 | | Key | Description | 35 | |----------------|--------------------------------------------------------------------------------------------------------| 36 | | **RR_MODE** | Identifies what mode worker should work with (`http`, `temporal`, `grpc`, `jobs`, `tcp`, `centrifuge`) | 37 | | **RR_RPC** | Contains RPC connection address when enabled. | 38 | | **RR_RELAY** | `pipes` or `tcp://...`, depends on server relay configuration. | 39 | | **RR_VERSION** | RoadRunner version started the PHP worker (minimum `2023.1.0`) | 40 | 41 | These default environment values can be used within your PHP worker to configure various settings and adapt the worker's 42 | behavior according to the specific requirements of your application. 43 | 44 | ## What's Next? 45 | 46 | 1. [Environment variables](../intro/config.md) - Learn how to use environment variables in your RoadRunner 47 | configuration. -------------------------------------------------------------------------------- /docs/en/php/rpc.md: -------------------------------------------------------------------------------- 1 | # PHP Workers — RPC to RoadRunner 2 | 3 | RoadRunner provides a powerful RPC (Remote Procedure Call) interface for communication between PHP applications and the 4 | server using [Goridge library](https://github.com/roadrunner-php/goridge). 5 | 6 | ## Goridge 7 | 8 | Goridge is a high-performance PHP-to-Golang/Golang-to-PHP library developed specifically for communication between PHP 9 | applications and RoadRunner. It is designed to provide a reliable and efficient way to communicate between the two 10 | components, allowing PHP developers to take advantage of the performance benefits of Golang-based systems while still 11 | writing their applications in PHP. 12 | 13 | ## Installation 14 | 15 | To use Goridge, you first need to install it via Composer. 16 | 17 | ```terminal 18 | composer require spiral/goridge 19 | ``` 20 | 21 | ## Configuration 22 | 23 | You can change the RPC port from the default (`127.0.0.1:6001`) using the following configuration: 24 | 25 | ```yaml 26 | version: "3" 27 | 28 | rpc: 29 | listen: tcp://127.0.0.1:6001 30 | ``` 31 | 32 | ## Connecting to RoadRunner 33 | 34 | Once you have installed Goridge, you can connect to the RoadRunner server. To do so, create an instance of 35 | the `Spiral\Goridge\RPC\RPC`. 36 | 37 | **Here's an example:** 38 | 39 | ```php 40 | getRPCAddress(); 60 | $rpc = new Goridge\RPC\RPC( 61 | Goridge\Relay::create($address) 62 | ); 63 | ``` 64 | 65 | > **Warning** 66 | > The `Environment::getRPCAddress()` method returns the RPC address from the `RR_RPC` environment variable and can be 67 | > used only inside PHP worker. 68 | 69 | ## Calling RPC Methods 70 | 71 | Once you have created `$rpc` instance, you can use it to call embedded RPC services. 72 | 73 | ```php 74 | $result = $rpc->call('informer.Workers', 'http'); 75 | 76 | var_dump($result); 77 | ``` 78 | 79 | > **Note** 80 | > In the case of running workers in debug mode `http: { pool.debug: true }` the number of http workers will be zero 81 | > (i.e. an empty array `[]` will be returned). 82 | > 83 | > This behavior may be changed in the future, you should not rely on this result to check that the 84 | > RoadRunner was launched in development mode. 85 | 86 | ## Available RPC Methods 87 | 88 | RoadRunner provides several built-in RPC methods that you can use in your PHP applications: 89 | 90 | - `rpc.Version`: Returns the RoadRunner version. 91 | - `rpc.Config`: Returns the RoadRunner configuration. 92 | 93 | There are also several plugins that provide RPC methods, but not described in the documentation. You may be able to find 94 | the RPC Go definitions for these plugins in the following repositories: 95 | 96 | - [Jobs](https://github.com/roadrunner-server/jobs/blob/master/rpc.go) - Provides a way to create and manage job 97 | pipelines and push jobs to the queue. 98 | - [KV](https://github.com/roadrunner-server/kv/blob/master/rpc.go) - Provides a way to store and retrieve key-value 99 | pairs. 100 | - [Informer](https://github.com/roadrunner-server/informer/blob/master/rpc.go) 101 | - [Resetter](https://github.com/roadrunner-server/resetter/blob/master/rpc.go) - Provides a way to reset workers 102 | globally or separately for each plugin. 103 | - [Status](https://github.com/roadrunner-server/status/blob/master/rpc.go) 104 | - [Metrics](https://github.com/roadrunner-server/metrics/blob/master/rpc.go) 105 | - [Lock](../plugins/locks.md) - Provides a way to obtain and release locks on 106 | resources. [GitHub](https://github.com/roadrunner-server/lock/blob/master/rpc.go) 107 | - [Service](../plugins/service.md) - Provides a simple API to monitor and control 108 | processes [GitHub](https://github.com/roadrunner-server/service/blob/master/rpc.go) 109 | - [RPC](https://github.com/roadrunner-server/rpc/blob/master/rpc.go) 110 | 111 | ## What's Next? 112 | 113 | 1. [Writing a custom plugin](../customization/plugin.md) - Learn how to create your own services and RPC methods. -------------------------------------------------------------------------------- /docs/en/php/scaling.md: -------------------------------------------------------------------------------- 1 | # Dynamic Worker Scaling 2 | 3 | ## Introduction 4 | 5 | This feature became available starting from the RoadRunner `2023.3` release. 6 | Users can now scale their RoadRunner workers dynamically via RPC. 7 | A new class, `Spiral\RoadRunner\WorkerPool`, has been introduced to provide an easy interface to **add** or **remove** 8 | workers from the RoadRunner workers pool. 9 | 10 | ### Limitations 11 | - This feature is not available when running RoadRunner in debug mode (`pool.debug=true`). 12 | 13 | ### Usage 14 | 15 | Below is a brief example demonstrating how to use this new feature: 16 | 17 | ```php 18 | use Spiral\RoadRunner\WorkerPool; 19 | use Spiral\Goridge\RPC\RPC; 20 | 21 | $rpc = RPC::create('tcp://127.0.0.1:6001'); 22 | $pool = new WorkerPool($rpc); 23 | 24 | // Add a worker to the pool. 25 | $pool->addWorker('http'); 26 | 27 | // Remove a worker from the pool. 28 | $pool->removeWorker('http'); 29 | ``` 30 | 31 | ### List of the supported plugins: 32 | - `http`, `grpc`, `temporal`, `centrifuge`, `tcp`, `jobs`. 33 | 34 | This provides developers more control and flexibility over their RoadRunner setup, 35 | allowing for better resource allocation based on the needs of their application. 36 | -------------------------------------------------------------------------------- /docs/en/plugins/config.md: -------------------------------------------------------------------------------- 1 | # Plugins — Config 2 | 3 | The config plugin is an essential component in RoadRunner, responsible for parsing configuration files and environment 4 | variables. It serves as a central hub for managing configurations for the plugins and RoadRunner server itself. 5 | 6 | ## Configuration File Structure 7 | 8 | The RoadRunner configuration file should be formatted using **YAML** or **JSON**. Each configuration file must include 9 | a `version` at the top, indicating the format's version. The currently supported configuration version is **version 3**. 10 | 11 | > **Warning** 12 | > The configuration version is not synonymous with the RoadRunner (RR) version. The configuration version and RR version 13 | > have separate versioning systems. 14 | 15 | **Example of a YAML configuration file:** 16 | 17 | ```yaml 18 | version: '3' 19 | 20 | # ... other config values 21 | ``` 22 | 23 | > **Warning** 24 | > Version numbers are strings, not numbers. For example, `version: "3"` is correct, but `version: 3` is not. 25 | 26 | ### Compatibility matrix 27 | 28 | The compatibility matrix provides information about the supported configuration versions for different RoadRunner 29 | versions. 30 | 31 | | RR version | Configuration version | 32 | |----------------|--------------------------------------------------------------------------------| 33 | | **>=2023.x.x** | **3** | 34 | | **>=2.8** | **2.7** | 35 | | **2.7.x** | **2.7** `OR` Unversioned (treated as `v2.6.0`, will be auto-updated to `v2.7`) | 36 | | **<=2.6.x** | Doesn't support versions | 37 | 38 | > **Note** 39 | > *non-versioned: configuration used in the 2.0.x-2.6.x releases. 40 | 41 | ## Changelog 42 | 43 | ### v3.0 Configuration 44 | 45 | #### Reload plugin Update 46 | 47 | ⚠️ The `reload` plugin has been removed from the default plugins list. Please use `*.pool.debug=true` instead. 48 | 49 | #### OpenTelemetry Middleware Update 50 | 51 | Starting from version **v2023.1.0**, the OpenTelemetry (OTEL) middleware configuration has been moved out of the HTTP 52 | plugin to support its usage across multiple plugins, including HTTP, gRPC, jobs and temporal. The OTEL middleware is now 53 | configured using a top-level YAML key. 54 | 55 | **RoadRunner 2.x** 56 | 57 | ```yaml 58 | # HTTP plugin settings. 59 | http: 60 | ... 61 | middleware: [ "otel" ] 62 | otel: 63 | insecure: true 64 | compress: false 65 | client: http 66 | exporter: otlp 67 | custom_url: "" 68 | service_name: "rr_test" 69 | service_version: "1.0.0" 70 | endpoint: "127.0.0.1:4318" 71 | ``` 72 | 73 | **RoadRunner v2023.x.x** 74 | 75 | ```yaml 76 | http: 77 | ... 78 | middleware: [ "otel" ] 79 | 80 | otel: 81 | insecure: true 82 | compress: false 83 | client: http 84 | exporter: otlp 85 | custom_url: "" 86 | service_name: "rr_test" 87 | service_version: "1.0.0" 88 | endpoint: "127.0.0.1:4318" 89 | ``` 90 | 91 | ## Updating from `version: 2.7` to `version: 3` 92 | 93 | To update your configuration from version 2.7 to version 3, follow these steps: 94 | 95 | 1. **Update the version number:** Change the `version` value from `2.7` to `3`. 96 | 2. **Relocate the `otel` middleware configuration:** If your configuration uses the `otel` middleware configuration 97 | within the `http` plugin, move it to the configuration root by cutting it from the `http` plugin and pasting it at 98 | the root level. 99 | 3. **Remove** the `reload` plugin configuration and if needed, use the `*.pool.debug=true` option instead. 100 | 101 | ## Tips 102 | 103 | 1. By default, `.rr.yaml` used as the configuration, located in the same directory with RR binary. 104 | 105 | -------------------------------------------------------------------------------- /docs/en/plugins/intro.md: -------------------------------------------------------------------------------- 1 | # Plugins — What is it? 2 | 3 | RoadRunner boasts a powerful plugin system that not only comes with an extensive suite of pre-built plugins, but also 4 | allows developers to create their own custom plugins and share them with the community. This versatility makes 5 | RoadRunner an adaptable and flexible solution for a wide range of applications and use cases. 6 | 7 | ## Available plugins 8 | 9 | RoadRunner offers numerous plugins out of the box, designed to cater to common requirements and streamline the 10 | development process. Some of the most notable plugins include: 11 | 12 | - [**Centrifuge**](./centrifuge.md): Real-time websocket messaging and broadcasting. 13 | - [**HTTP**](../http/http.md): Efficient and scalable HTTP server implementation. 14 | - [**Logger**](../lab/logger.md): Robust logging capabilities for various output formats and destinations. 15 | - [**App-Logger**](../lab/applogger.md): Send application logs to the RoadRunner logger from PHP application. 16 | - [**gRPC**](./grpc.md): Efficient and scalable gRPC server implementation. 17 | - [**Temporal**](../workflow/temporal.md): Workflow and task orchestration with distributed computing capabilities. 18 | - [**Server**](./server.md): Core server functionality and lifecycle management. 19 | - [**Service**](./service.md): Start and monitor services like a supervisor. 20 | - [**Locks**](./locks.md): Distributed locking mechanisms for concurrency control. 21 | - [**TCP**](./tcp.md): High-performance TCP server for custom networking solutions. 22 | - [**Metrics**](../lab/metrics.md): Application-level metrics and monitoring. 23 | - [**KV**](../kv/overview.md): Key-value store interface for storage and retrieval of data. 24 | - [**Jobs**](../queues/overview.md): Background job processing and management. 25 | - [**HealthChecks**](../lab/health.md): Health monitoring and reporting for system components. 26 | - [**OpenTelemetry (otel)**](../lab/otel.md): Distributed tracing and observability with OpenTelemetry integration. 27 | 28 | ## Custom Plugins 29 | 30 | In addition, RoadRunner encourages developers to create their own custom plugins, tailored to meet specific requirements 31 | or extend the core functionality. By creating plugins in Go, developers can tap into the performance, concurrency, and 32 | scalability benefits that Go offers, while still using PHP for the core application logic. 33 | 34 | To get started with custom plugin development, refer to [Writing Plugins](../customization/plugin.md) 35 | and [HTTP Middleware](../customization/middleware.md) documentation. It provides a comprehensive guide on how to 36 | create, test, and integrate your own plugins into RoadRunner. 37 | 38 | ## Community Sharing 39 | 40 | RoadRunner fosters a collaborative ecosystem by encouraging developers to share their custom plugins with the community. 41 | By sharing your work, you contribute to a growing library of plugins, which in turn helps other developers find 42 | solutions to their challenges and fosters innovation. 43 | 44 | If you've developed a custom plugin that you believe would benefit others, consider submitting it to the RoadRunner 45 | Plugin Repository, where it can be discovered and used by the broader community. 46 | -------------------------------------------------------------------------------- /docs/en/plugins/locks.md: -------------------------------------------------------------------------------- 1 | # Plugins — Lock 2 | 3 | The RoadRunner lock plugin is a powerful tool that enables you to manage resource locks in their applications using the 4 | RPC protocol. By leveraging the benefits of using GO with PHP, it provides a lightweight, fast, and reliable way to 5 | acquire, release, and manage locks. With this plugin, you can easily manage critical sections of your application and 6 | prevent race conditions, data corruption, and other synchronization issues that can occur in multi-process environments. 7 | 8 | > **Warning** 9 | > RoadRunner lock plugin uses an in-memory storage to store information about locks at this moment. When multiple 10 | > instances of RoadRunner are used, each instance will have its own in-memory storage for locks. As a result, if a 11 | > process 12 | > acquires a lock on one instance of RoadRunner, it will not be aware of the lock state on the other instances. 13 | 14 | ## PHP client 15 | 16 | The RoadRunner lock plugin comes with a convenient PHP package that simplifies the process of integrating the 17 | plugin with your PHP application. 18 | 19 | ### Installation 20 | 21 | To get started, you can install the package via Composer using the following command: 22 | 23 | ```terminal 24 | composer require roadrunner-php/lock 25 | ``` 26 | 27 | ### Usage 28 | 29 | After the installation, you can create an instance of the `RoadRunner\Lock\Lock` class, which will allow you to use the 30 | available class methods. 31 | 32 | **Here is an example:** 33 | 34 | ```php 35 | use RoadRunner\Lock\Lock; 36 | use Spiral\Goridge\RPC\RPC; 37 | 38 | require __DIR__ . '/vendor/autoload.php'; 39 | 40 | $lock = new Lock(RPC::create('tcp://127.0.0.1:6001')); 41 | ``` 42 | 43 | > **Warning** 44 | > To interact with the RoadRunner lock plugin, you will need to have the RPC defined in the rpc configuration 45 | > section. You can refer to the documentation page [here](../php/rpc.md) to learn more about the configuration and 46 | > installation. 47 | 48 | The `RoadRunner\Lock\Lock` class provides four methods that allow you to manage locks: 49 | 50 | #### Acquire lock 51 | 52 | Locks a resource so that it can be accessed by one process at a time. When a resource is locked, other processes that 53 | attempt to lock the same resource will be blocked until the lock is released. 54 | 55 | ```php 56 | $id = $lock->lock('pdf:create'); 57 | 58 | // Acquire lock with ttl - 10 microseconds 59 | $id = $lock->lock('pdf:create', ttl: 10); 60 | // or 61 | $id = $lock->lock('pdf:create', ttl: new \DateInterval('PT10S')); 62 | 63 | // Acquire lock and wait 5 microseconds until lock will be released 64 | $id = $lock->lock('pdf:create', wait: 5); 65 | // or 66 | $id = $lock->lock('pdf:create', wait: new \DateInterval('PT5S')); 67 | 68 | // Acquire lock with id - 14e1b600-9e97-11d8-9f32-f2801f1b9fd1 69 | $id = $lock->lock('pdf:create', id: '14e1b600-9e97-11d8-9f32-f2801f1b9fd1'); 70 | ``` 71 | 72 | #### Acquire read lock 73 | 74 | Locks a resource for shared access, allowing multiple processes to access the resource simultaneously. When a resource 75 | is locked for shared access, other processes that attempt to lock the resource for exclusive access will be blocked 76 | until all shared locks are released. 77 | 78 | ```php 79 | $id = $lock->lockRead('pdf:create', ttl: 100000); 80 | // or 81 | $id = $lock->lockRead('pdf:create', ttl: new \DateInterval('PT10S')); 82 | 83 | // Acquire lock and wait 5 microseconds until lock will be released 84 | $id = $lock->lockRead('pdf:create', wait: 5); 85 | // or 86 | $id = $lock->lockRead('pdf:create', wait: new \DateInterval('PT5S')); 87 | 88 | // Acquire lock with id - 14e1b600-9e97-11d8-9f32-f2801f1b9fd1 89 | $id = $lock->lockRead('pdf:create', id: '14e1b600-9e97-11d8-9f32-f2801f1b9fd1'); 90 | ``` 91 | 92 | #### Release lock 93 | 94 | Releases an exclusive lock or read lock on a resource that was previously acquired by a call to `lock()` 95 | or `lockRead()`. 96 | 97 | ```php 98 | // Release lock after task is done. 99 | $lock->release('pdf:create', $id); 100 | 101 | // Force release lock 102 | $lock->forceRelease('pdf:create'); 103 | ``` 104 | 105 | #### Check lock 106 | 107 | Checks if a resource is currently locked and returns information about the lock. 108 | 109 | ```php 110 | $status = $lock->exists('pdf:create'); 111 | if($status) { 112 | // Lock exists 113 | } else { 114 | // Lock not exists 115 | } 116 | ``` 117 | 118 | #### Update TTL 119 | 120 | Updates the time-to-live (TTL) for the locked resource. 121 | 122 | ```php 123 | // Add 10 microseconds to lock ttl 124 | $lock->updateTTL('pdf:create', $id, 10); 125 | // or 126 | $lock->updateTTL('pdf:create', $id, new \DateInterval('PT10S')); 127 | ``` 128 | 129 | ## Symfony integration 130 | 131 | #### Installation 132 | 133 | You can install the package via composer: 134 | 135 | ```bash 136 | composer require roadrunner-php/symfony-lock-driver 137 | 138 | ``` 139 | 140 | #### Usage 141 | 142 | ```php 143 | use RoadRunner\Lock\Lock; 144 | use Spiral\Goridge\RPC\RPC; 145 | use Spiral\RoadRunner\Symfony\Lock\RoadRunnerStore; 146 | use Symfony\Component\Lock\LockFactory; 147 | 148 | require __DIR__ . '/vendor/autoload.php'; 149 | 150 | $lock = new Lock(RPC::create('tcp://127.0.0.1:6001')); 151 | $factory = new LockFactory( 152 | new RoadRunnerStore($lock) 153 | ); 154 | ``` 155 | 156 | Read more about using a Symfony Lock component [here](https://symfony.com/doc/current/components/lock.html). 157 | 158 | ## API 159 | 160 | ### Protobuf API 161 | 162 | To make it easy to use the Lock proto API in PHP, we provide 163 | a [GitHub repository](https://github.com/roadrunner-php/roadrunner-api-dto), that contains all the generated 164 | PHP DTO classes proto files, making it easy to work with these files in your PHP application. 165 | 166 | - [API](https://buf.build/roadrunner-server/api/file/main:lock/v1beta1/lock.proto) 167 | 168 | ### RPC API 169 | 170 | RoadRunner provides an RPC API, which allows you to manage locks in your applications using remote procedure calls. The 171 | RPC API provides a set of methods that map to the available methods of the `RoadRunner\Lock\Lock` class in PHP. 172 | 173 | #### Lock 174 | 175 | Acquires an exclusive lock on a resource so that it can be accessed by one process at a time. When a resource is locked, 176 | other processes that attempt to lock the same resource will be blocked until the lock is released. 177 | 178 | ```go 179 | func (r *rpc) Lock(req *lockApi.Request, resp *lockApi.Response) error {} 180 | ``` 181 | 182 | #### LockRead 183 | 184 | Acquires a read lock on a resource, allowing multiple processes to access the resource simultaneously. When a resource 185 | is locked for shared access, other processes that attempt to lock the resource for exclusive access will be blocked 186 | until all shared locks are released. 187 | 188 | ```go 189 | func (r *rpc) LockRead(req *lockApi.Request, resp *lockApi.Response) error {} 190 | ``` 191 | 192 | #### Release 193 | 194 | Releases an exclusive lock or a read lock on a resource that was previously acquired by a call to `Lock` or `LockRead`. 195 | 196 | ```go 197 | func (r *rpc) Release(req *lockApi.Request, resp *lockApi.Response) error {} 198 | ``` 199 | 200 | #### ForceRelease 201 | 202 | Releases all locks on a resource, regardless of which process acquired them. 203 | 204 | ```go 205 | func (r *rpc) ForceRelease(req *lockApi.Request, resp *lockApi.Response) error {} 206 | ``` 207 | 208 | #### Exists 209 | 210 | Checks if a resource is currently locked and returns information about the lock. 211 | 212 | ```go 213 | func (r *rpc) Exists(req *lockApi.Request, resp *lockApi.Response) error {} 214 | ``` 215 | 216 | #### UpdateTTL 217 | 218 | Updates the time-to-live (TTL) for the locked resource. 219 | 220 | ```go 221 | func (r *rpc) UpdateTTL(req *lockApi.Request, resp *lockApi.Response) error {} 222 | ``` 223 | -------------------------------------------------------------------------------- /docs/en/plugins/server.md: -------------------------------------------------------------------------------- 1 | # Plugins — Server 2 | 3 | RoadRunner server plugin, is responsible for starting worker pools for plugins that use workers, such as `http`, `tcp`, 4 | `jobs`, `centrifuge`, `temporal`, and `grpc`. The worker pools inherit all of RoadRunner's features, such as 5 | supervising, state machine, and command handling. 6 | 7 | ## Configuration 8 | 9 | The `server` section contains various options for configuring the plugin. 10 | 11 | **Here is an example of a configuration:** 12 | 13 | ```yaml .rr.yaml 14 | server: 15 | on_init: 16 | # Command to execute before the main server's command 17 | # 18 | # This option is required if using on_init 19 | command: "any php or script here" 20 | 21 | # Username (not UID) of the user from whom the on_init command is executed. An empty value means to use the RR process user. 22 | # 23 | # Default: "" 24 | user: "" 25 | 26 | # Script execute timeout 27 | # 28 | # Default: 60s [60m, 60h], if used w/o units its means - NANOSECONDS. 29 | exec_timeout: 20s 30 | 31 | # Environment variables for the worker processes. 32 | # 33 | # Default: 34 | env: 35 | - SOME_KEY: "SOME_VALUE" 36 | - SOME_KEY2: "SOME_VALUE2" 37 | 38 | # Worker starting command, with any required arguments. 39 | # 40 | # This option is required. 41 | command: "php psr-worker.php" 42 | 43 | # Username (not UID) for the worker processes. An empty value means to use the RR process user. 44 | # 45 | # Default: "" 46 | user: "" 47 | 48 | # Group name (not GID) for the worker processes. An empty value means to use the RR process user. 49 | # 50 | # Default: "" 51 | group: "" 52 | 53 | # Environment variables for the worker processes. 54 | # 55 | # Default: 56 | env: 57 | - SOME_KEY: "SOME_VALUE" 58 | - SOME_KEY2: "SOME_VALUE2" 59 | 60 | relay: pipes 61 | 62 | # Timeout for relay connection establishing (only for socket and TCP port relay). 63 | # 64 | # Default: 60s 65 | relay_timeout: 60s 66 | ``` 67 | 68 | > **Note** 69 | > Worker relay can be: `pipes`, TCP (eg.: `tcp://127.0.0.1:6002`), or socket (eg.: `unix:///var/run/rr.sock`). But in 70 | > most cases, you should use the default `pipes` relay, it is the fastest communication transport. 71 | > It uses an inter-process communication mechanism that allows for fast and efficient communication between 72 | > processes. It does not require any network connections or external libraries, making it a lightweight and fast option. 73 | 74 | > **Note** 75 | > Use `on_init.user` option to execute the on_init command under a different user. 76 | 77 | ### Server initialization 78 | 79 | The `on_init` section is used for application initialization or warming up before starting workers. It allows you to set 80 | a command script that will be executed before starting the workers. You can also set environment variables to pass to 81 | this script. 82 | 83 | > **Note** 84 | > If the `on_init` command fails (i.e., returns a non-zero exit code), RoadRunner will log the error but continue 85 | > execution. This ensures that a failure during initialization does not interrupt the application's operation. 86 | 87 | ### Worker starting command 88 | 89 | The `server.command` option is required and is used to start the worker pool for each configured section in the config. 90 | 91 | > **Note** 92 | > This option can be overridden by plugins with a pool section, such as the `http.pool.command`, or in general `.pool.command`. 93 | 94 | The `user` and `group` options allow you to set the user and group that will start and own the worker process. This 95 | feature provides an additional layer of security and control over the application's execution environment. 96 | 97 | > **Note** 98 | > An empty value means to use the RoadRunner process user. 99 | 100 | > **Warning** 101 | > RoadRunner must be started from the root user. Root access is needed only to fork the process under a 102 | > different user. Once the worker process is started, it will run with the specified user and group permissions, 103 | > providing a secure and controlled execution environment for the application. All temporary files (`http` for example) 104 | > would be created with the provided user/group 105 | 106 | The `env` option allows you to set environment variables to pass to the worker script. 107 | 108 | ## PHP Client 109 | 110 | There is a package that simplifies the process of integrating the RoadRunner worker pool with a PHP application. The 111 | package contains a common codebase for all RoadRunner workers, making it easy to integrate and communicate with workers 112 | created by RoadRunner. 113 | 114 | When RoadRunner creates workers for any plugin that uses workers, it runs a PHP script and starts communicating with it 115 | using a relay. The relay can be `pipes`, `TCP`, or a `socket`. The PHP client simplifies this process by providing a 116 | convenient interface for sending and receiving payloads to and from the worker. 117 | 118 | **Here is an example of simple PHP worker:** 119 | 120 | ```php worker.php 121 | waitPayload()) { 129 | // Received Payload 130 | var_dump($data); 131 | 132 | // Respond Answer 133 | $worker->respond(new \Spiral\RoadRunner\Payload('DONE')); 134 | } 135 | ``` 136 | 137 | The worker waits for incoming payloads, for example `HTTP request`, `TCP request`, `Queue task` or`Centrifuge message`, 138 | processes them, and sends a response back to the server. Once a payload is received, the worker processes it and sends a 139 | response using the `respond` method. 140 | 141 | ## What's Next? 142 | 143 | 1. [PHP Workers](../php/worker.md) - Read more about PHP workers. 144 | -------------------------------------------------------------------------------- /docs/en/plugins/tcp.md: -------------------------------------------------------------------------------- 1 | # Plugins — TCP 2 | 3 | The RoadRunner TCP plugin helps you handle TCP requests. You can use this plugin to make your own servers like an SMTP 4 | server, and send TCP requests directly to PHP workers for handling. 5 | 6 | ## Principle of work 7 | 8 | The RoadRunner TCP plugin operates by receiving client requests and proxying them to free PHP workers that are not 9 | currently processing any request. 10 | 11 | > **Warning** 12 | > It's essential to note that PHP workers are stateless, meaning you cannot save the context of a request between 13 | > multiple requests from a single client. Instead, you must use external storage, for 14 | > example [Key Value](../kv/overview.md), to maintain context and rely on the connection UUID to identify requests from 15 | > individual clients. 16 | 17 | The request sent to the PHP worker contains the following context: 18 | 19 | - `event` - The event type. The following events are supported: 20 | - `CONNECTED`: Sent when a client connects to the server. 21 | - `DATA`: Sent when a client sends data to the server. 22 | - `CLOSED`: Sent when a client disconnects from the server. 23 | - `remote_addr`: The client's IP address. 24 | - `server`: The server name, as specified in the RoadRunner configuration (e.g., `smtp`, `server2`). 25 | - `body`: The request body. 26 | - `uuid`: The connection UUID. 27 | 28 | The protocol used by the RoadRunner TCP plugin provides a bidirectional communication channel between the PHP worker 29 | and the RoadRunner server. This design allows PHP workers to send responses back to the client, enabling seamless 30 | handling of client requests and communication between all parties. 31 | 32 | ## Configuration 33 | 34 | The TCP plugin is configured via the `tcp` section of the RoadRunner configuration file. 35 | 36 | **Here is an example configuration:** 37 | 38 | :::: tabs 39 | 40 | ::: tab Server command 41 | 42 | ```yaml .rr.yaml 43 | server: 44 | command: "php tcp-worker.php" 45 | 46 | tcp: 47 | servers: 48 | smtp: 49 | addr: tcp://127.0.0.1:1025 50 | delimiter: "\r\n" # by default 51 | 52 | server2: 53 | addr: tcp://127.0.0.1:8889 54 | 55 | pool: 56 | num_workers: 2 57 | max_jobs: 0 58 | allocate_timeout: 60s 59 | destroy_timeout: 60s 60 | ``` 61 | 62 | > **Note** 63 | > You can define command to start server in the `server.command` section:. It will be used to start PHP workers for all 64 | > registered plugins, such as `grpc`, `http`, `jobs`, etc. 65 | 66 | ::: 67 | 68 | ::: tab Worker commands 69 | You can also define command to start server in the `grpc.pool.command` section to separate server and grpc workers. 70 | 71 | ```yaml .rr.yaml 72 | server: 73 | command: "php worker.php" 74 | 75 | tcp: 76 | servers: 77 | smtp: 78 | addr: tcp://127.0.0.1:1025 79 | delimiter: "\r\n" # by default 80 | 81 | server2: 82 | addr: tcp://127.0.0.1:8889 83 | 84 | pool: 85 | command: "php tcp-worker.php" 86 | num_workers: 2 87 | max_jobs: 0 88 | allocate_timeout: 60s 89 | destroy_timeout: 60s 90 | ``` 91 | 92 | ::: 93 | :::: 94 | 95 | #### Configuration Parameters 96 | 97 | - `servers`: A list of TCP servers to start. Each server should contain the following keys: 98 | - `addr`: The server address and port, specified in the format `tcp://:`. 99 | - `delimiter`: (Optional) The data packet delimiter. By default, it is set to `\r\n`. Each data packet should end 100 | either with an `EOF` or the specified delimiter. 101 | - `read_buf_size`: (Optional) The size of the read buffer in MB. To reduce the number of read syscalls, consider 102 | using a larger buffer size if you expect to receive large payloads on the TCP server. 103 | 104 | - `pool`: Configuration for the PHP worker pool. 105 | - `num_workers`: The number of PHP workers to allocate. 106 | - `max_jobs`: The maximum number of jobs each worker can handle. Set to 0 for no limit. 107 | - `allocate_timeout`: The timeout for worker allocation, specified in the format `s` (e.g., `60s` for 60 108 | seconds). 109 | - `destroy_timeout`: The timeout for worker destruction, specified in the same format as allocate_timeout. 110 | 111 | ## PHP client 112 | 113 | The RoadRunner TCP plugin comes with a convenient PHP package that simplifies the process of integrating the plugin with 114 | your PHP application. 115 | 116 | ### Installation 117 | 118 | To get started, you can install the package via Composer using the following command: 119 | 120 | ```terminal 121 | composer require spiral/roadrunner-tcp 122 | ``` 123 | 124 | ### Usage 125 | 126 | The following example demonstrates how to create a simple PHP worker: 127 | 128 | ```php tcp-worker.php 129 | require __DIR__ . '/vendor/autoload.php'; 130 | 131 | use Spiral\RoadRunner\Worker; 132 | use Spiral\RoadRunner\Tcp\TcpWorker; 133 | use Spiral\RoadRunner\Tcp\TcpResponse; 134 | use Spiral\RoadRunner\Tcp\TcpEvent; 135 | 136 | // Create new RoadRunner worker from global environment 137 | $worker = Worker::create(); 138 | 139 | $tcpWorker = new TcpWorker($worker); 140 | 141 | while ($request = $tcpWorker->waitRequest()) { 142 | 143 | try { 144 | if ($request->event === TcpEvent::Connected) { 145 | // You can close connection according to your restrictions 146 | if ($request->remoteAddr !== '127.0.0.1') { 147 | $tcpWorker->close(); 148 | continue; 149 | } 150 | 151 | // Or continue reading data from the server 152 | // By default, the server closes the connection if a worker 153 | // doesn't send a CONTINUE response 154 | $tcpWorker->read(); 155 | 156 | // Or send a response to the TCP connection, for example, to an SMTP client 157 | $tcpWorker->respond("220 mailamie \r\n"); 158 | 159 | } elseif ($request->event === TcpEvent::Data) { 160 | 161 | $body = $request->body; 162 | 163 | // Handle request from TCP server [tcp_access_point_1] 164 | if ($request->server === 'tcp_access_point_1') { 165 | 166 | // Send response and close connection 167 | $tcpWorker->respond('Access denied', TcpResponse::RespondClose); 168 | 169 | // Handle request from TCP server [server2] 170 | } elseif ($request->server === 'server2') { 171 | 172 | // Send response to the TCP connection and wait for the next request 173 | $tcpWorker->respond(\json_encode([ 174 | 'remote_addr' => $request->remoteAddr, 175 | 'server' => $request->server, 176 | 'uuid' => $request->connectionUuid, 177 | 'body' => $request->body, 178 | 'event' => $request->event 179 | ])); 180 | } 181 | 182 | // Handle closed connection event 183 | } elseif ($request->event === TcpEvent::Close) { 184 | // Do something 185 | 186 | // You don't need to send a response on a closed connection 187 | } 188 | 189 | } catch (\Throwable $e) { 190 | $tcpWorker->respond("Something went wrong\r\n", TcpResponse::RespondClose); 191 | $worker->error((string)$e); 192 | } 193 | } 194 | ``` 195 | 196 | ## What's Next? 197 | 198 | 1. [Plugins — KV](../kv/overview.md) - Learn how to use the Key Value plugin to store data between requests. 199 | -------------------------------------------------------------------------------- /docs/en/queues/beanstalk.md: -------------------------------------------------------------------------------- 1 | # Jobs — Beanstalk Driver 2 | 3 | Beanstalk is a simple and fast general purpose work queue. To install Beanstalk, you can use 4 | the [local queue server](https://github.com/beanstalkd/beanstalkd) or run the server 5 | inside [AWS Elastic](https://aws.amazon.com/elasticbeanstalk/). You can choose any option that is convenient for you. 6 | 7 | Setting up the server is similar to setting up AMQP and requires specifying the connection in the `beanstalk` section of 8 | your RoadRunner configuration file. 9 | 10 | ```yaml .rr.yaml 11 | beanstalk: 12 | addr: tcp://127.0.0.1:11300 13 | ``` 14 | 15 | ## Configuration 16 | 17 | ```yaml .rr.yaml 18 | version: "3" 19 | 20 | beanstalk: 21 | # Optional section. 22 | # Default: tcp://127.0.0.1:11300 23 | addr: tcp://127.0.0.1:11300 24 | 25 | # Optional section. 26 | # Default: 30s 27 | timeout: 10s 28 | 29 | jobs: 30 | pipelines: 31 | # User defined name of the queue. 32 | beanstalk-pipeline-name: 33 | # Required section. 34 | # Should be "beanstalk" for the Beanstalk driver. 35 | driver: beanstalk 36 | 37 | config: # NEW in 2.7 38 | 39 | # Optional section. 40 | # Default: 10 41 | priority: 10 42 | 43 | # Consume any payload type (not only Jobs structured) 44 | # Default: false 45 | consume_all: false 46 | 47 | # Optional section. 48 | # Default: 1 49 | tube_priority: 1 50 | 51 | # Optional section. 52 | # Default: default 53 | tube: default 54 | 55 | # Optional section. 56 | # Default: 5s 57 | reserve_timeout: 5s 58 | ``` 59 | 60 | ## Configuration options 61 | 62 | **Here is a detailed description of each of the beanstalk-specific options:** 63 | 64 | ### Priority 65 | 66 | `priority` - Similar to the same option in other drivers. This is queue default priority for each task pushed into this 67 | queue if the priority value for these tasks was not explicitly set. Lower value - higher priority. 68 | 69 | ### Tube priority 70 | 71 | `tube_priority` - The value for specifying the priority within Beanstalk is the internal priority of the server. The 72 | value should not exceed `int32` size. 73 | 74 | ### Tube 75 | 76 | `tube` - The name of the inner "tube" specific to the Beanstalk driver. 77 | 78 | ### Consume all 79 | 80 | `consume_all` - By default, RR supports only `Jobs` structures from the queue. Set this option to true if you want to 81 | also consume the raw payloads. -------------------------------------------------------------------------------- /docs/en/queues/boltdb.md: -------------------------------------------------------------------------------- 1 | # Jobs — Local (based on the boltdb) Driver 2 | 3 | This type of driver is already supported by RoadRunner and requires no additional installation. It uses boltdb as the 4 | main job store. This driver should be used locally for testing or development. It can be used in production, but this 5 | type of driver can't handle huge loads. The maximum RPS it can have is not more than 30-50. 6 | 7 | Data in this driver is stored in the boltdb database file. You can't use the same file at the same time for the 2 8 | pipelines or for the for KV plugin and Jobs plugin. This is a boltdb limitation on simultaneous access of 2 processes to 9 | the same file. 10 | 11 | ## Configuration 12 | 13 | ```yaml .rr.yaml 14 | version: "3" 15 | 16 | boltdb: 17 | permissions: 0777 18 | 19 | jobs: 20 | pipelines: 21 | # User defined name of the queue. 22 | example: 23 | # Required section. 24 | # Should be "boltdb" for the local driver. 25 | driver: boltdb 26 | 27 | config: # NEW in 2.7 28 | # Number of jobs to prefetch from the driver. 29 | # 30 | # Default: 100_000. 31 | prefetch: 10000 32 | 33 | # Pipeline priority 34 | # 35 | # If the job has priority set to 0, it will inherit the pipeline's priority. Default: 10. 36 | priority: 10 37 | 38 | # BoldDB file to create or DB to use 39 | # 40 | # Default: "rr.db" 41 | file: "path/to/rr.db" 42 | 43 | # Permissions for the boltdb database file 44 | # 45 | # This option is optional. Default: 0755 46 | permissions: 0755 47 | ``` 48 | 49 | ## Configuration options 50 | 51 | **Here is a detailed description of each of the boltdb-specific options:** 52 | 53 | ### Priority 54 | 55 | `priority` - Queue default priority for each task pushed into this queue, if the priority value for these tasks has not 56 | been explicitly set. 57 | 58 | Lower value - higher priority. For example, we have 2 pipelines `pipe1` with priority 1 and `pipe10` with priority 10. 59 | Jobs from `pipe10` will be taken by workers only if all jobs from `pipe1` are processed. 60 | 61 | ### Prefetch 62 | 63 | `prefetch` - A number of messages to receive from the local queue until ACK/NACK. 64 | 65 | ### File 66 | 67 | `file` - boltdb database file to use. Might be a full path with file: `/foo/bar/rr1.db`. 68 | 69 | Default: `rr.db`. 70 | 71 | ### Permissions 72 | 73 | `permissions` - Permissions for the boltdb database file. Default: `0755`. 74 | -------------------------------------------------------------------------------- /docs/en/queues/memory.md: -------------------------------------------------------------------------------- 1 | # Jobs — Memory Driver 2 | 3 | This type of driver is already supported by the RoadRunner and does not require any additional installations. 4 | 5 | Note that using this type of queue driver, all data is in memory and will be destroyed when the RoadRunner Server is 6 | restarted. If you need persistent queue, then it is recommended to use alternative drivers: `amqp`, `beanstalk` 7 | or `sqs`. 8 | 9 | > **Warning** 10 | > This driver cannot hold more than **1000 tasks** with delay at the same time (RR limitation) 11 | 12 | ## Configuration 13 | 14 | ```yaml .rr.yaml 15 | version: "3" 16 | 17 | jobs: 18 | pipelines: 19 | # User defined name of the queue. 20 | example: 21 | # Required section. 22 | # Should be "memory" for the in-memory driver. 23 | driver: memory 24 | 25 | config: # NEW in 2.7 26 | # Optional section. 27 | # Default: 10 28 | priority: 10 29 | 30 | # Optional section. 31 | # Default: 10 32 | prefetch: 10 33 | ``` 34 | 35 | ## Configuration options 36 | 37 | **Here is a detailed description of each of the in-memory-specific options:** 38 | 39 | ### Priority 40 | 41 | `priority` - Queue default priority for each task pushed into this queue if the priority value for these tasks was not 42 | explicitly set. Lower value - higher priority. 43 | 44 | **For example, we have 2 pipelines "pipe1" with priority 1 and "pipe10" with priority 10. Jobs from "pipe10" will be 45 | taken by workers only if all the jobs from "pipe1" are handled.** 46 | 47 | ### Prefetch 48 | 49 | `prefetch` - A local buffer between the PQ (priority queue) and driver. If the PQ size is set to 100 and prefetch to 50 | 100000, you'll be able to push up to prefetch number of jobs even if PQ is full. 51 | -------------------------------------------------------------------------------- /docs/en/queues/nats.md: -------------------------------------------------------------------------------- 1 | # Jobs — NATS Driver 2 | 3 | NATS driver supported in RR since `v2.5.0` and includes only NATS JetStream support. 4 | 5 | ## Configuration 6 | 7 | ```yaml .rr.yaml 8 | version: "3" 9 | 10 | nats: 11 | addr: "demo.nats.io" 12 | 13 | jobs: 14 | num_pollers: 10 15 | pipeline_size: 100000 16 | pool: 17 | num_workers: 10 18 | max_jobs: 0 19 | allocate_timeout: 60s 20 | destroy_timeout: 60s 21 | 22 | pipelines: 23 | test-1: 24 | driver: nats 25 | config: 26 | # Pipeline priority 27 | # If the job has priority set to 0, it will inherit the pipeline's priority. Default: 10. 28 | priority: 2 29 | 30 | # NATS prefetch 31 | # Messages to read into the channel 32 | prefetch: 100 33 | 34 | # Consume any payload type (not only Jobs structured) 35 | # Default: false 36 | consume_all: false 37 | 38 | # NATS subject 39 | # Default: default 40 | subject: default 41 | 42 | # NATS stream 43 | # Default: default-stream 44 | stream: foo 45 | 46 | # The consumer will only start receiving messages that were created after the consumer was created 47 | # Default: false (deliver all messages from the stream beginning) 48 | deliver_new: true 49 | 50 | # Consumer rate-limiter in bytes https://docs.nats.io/jetstream/concepts/consumers#ratelimit 51 | # Default: 1000 52 | rate_limit: 100 53 | 54 | # Delete the stream when after pipeline was stopped 55 | # Default: false 56 | delete_stream_on_stop: false 57 | 58 | # Delete message from the stream after successful acknowledge 59 | # Default: false 60 | delete_after_ack: false 61 | ``` 62 | 63 | ## Configuration options 64 | 65 | **Here is a detailed description of each of the nats-specific options:** 66 | 67 | ### Subject 68 | 69 | `subject` - nats [subject](https://docs.nats.io/nats-concepts/subjects). 70 | 71 | ### Stream 72 | 73 | `stream` - stream name. 74 | 75 | ### Deliver new 76 | 77 | `deliver_new` - the consumer will only start receiving messages that were created after the consumer was created. 78 | 79 | ### Rate limit 80 | 81 | `rate_limit` - NATS rate [limiter](https://docs.nats.io/jetstream/concepts/consumers#ratelimit). 82 | 83 | ### Delete stream on stop 84 | 85 | `delete_stream_on_stop` - delete the whole stream when pipeline stopped. 86 | 87 | ### Delete after ack 88 | 89 | `delete_after_ack` - delete message after it successfully acknowledged. 90 | 91 | ### Consume all 92 | 93 | `consume_all` - By default, RR supports only `Jobs` structures from the queue. Set this option to true if you want to 94 | also consume the raw payloads. -------------------------------------------------------------------------------- /docs/en/queues/sqs.md: -------------------------------------------------------------------------------- 1 | # Jobs — SQS Driver 2 | 3 | [Amazon SQS Simple Queue Service](https://aws.amazon.com/sqs/) is an alternative 4 | queue server also developed by Amazon and is also part of the AWS 5 | service infrastructure. If you prefer to use the "cloud" option, you can use the 6 | [prebuilt documentation](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configuring.html) 7 | for its installation. 8 | 9 | In addition to the ability to use this queue server within AWS, you can also use the 10 | can also use the local installation of this system on your own servers. If you prefer 11 | this option, you can use the [softwaremill's implementation](https://github.com/softwaremill/elasticmq) 12 | of the Amazon SQS server. 13 | 14 | After you have created the SQS server, you need to specify the following 15 | connection settings in the `sqs` configuration settings. Unlike AMQP and Beanstalk, 16 | SQS requires more values to set up a connection and will be different from what we are used to. 17 | we're used to. 18 | 19 | ## Configuration 20 | 21 | ```yaml .rr.yaml 22 | sqs: 23 | # Required AccessKey ID. 24 | # Default: empty 25 | key: access-key 26 | 27 | # Required secret access key. 28 | # Default: empty 29 | secret: api-secret 30 | 31 | # Required AWS region. 32 | # Default: empty 33 | region: us-west-1 34 | 35 | # Required AWS session token. 36 | # Default: empty 37 | session_token: test 38 | 39 | # Required AWS SQS endpoint to connect. 40 | # Default: http://127.0.0.1:9324 41 | endpoint: http://127.0.0.1:9324 42 | ``` 43 | 44 | > **Note** 45 | > Please note that although each of the sections contains default values, it is marked as "required". This means that in 46 | > almost all cases they are required to be specified in order to correctly configure the driver. 47 | 48 | After you have configured the connection - you should configure the queue that will use this connection: 49 | 50 | > **Note** 51 | > You may also skip the whole `sqs` configuration section (global, not the pipeline) to use the AWS IAM credentials if 52 | > the RR is inside the EC2 machine. RR will try to detect env automatically by making a http request to 53 | > the `http://169.254.169.254/latest/dynamic/instance-identity/` as 54 | > pointer [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html) 55 | 56 | ```yaml .rr.yaml 57 | version: "3" 58 | 59 | sqs: 60 | # SQS connection configuration... 61 | 62 | jobs: 63 | pipelines: 64 | test-sqs-pipeline: 65 | # Required section. 66 | # Should be "sqs" for the Amazon SQS driver. 67 | driver: sqs 68 | 69 | config: 70 | # Optional section. 71 | # Default: 10 72 | prefetch: 10 73 | 74 | # Consume any payload type (not only Jobs structured) 75 | # Default: false 76 | consume_all: false 77 | 78 | # Get queue URL only 79 | # Default: false 80 | skip_queue_declaration: false 81 | 82 | # Optional section. 83 | # Default: 0 84 | visibility_timeout: 0 85 | 86 | # Optional section. 87 | # Default: 0 88 | wait_time_seconds: 0 89 | 90 | # Optional section. 91 | # Default: default 92 | queue: default 93 | 94 | # Message group ID: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#SQS-SendMessage-request-MessageGroupId 95 | # Default: empty, should be set if FIFO queue is used 96 | message_group_id: "test" 97 | 98 | # Optional section. 99 | # Default: empty 100 | attributes: 101 | DelaySeconds: 42 102 | # etc... see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html 103 | 104 | # Optional section. 105 | # Default: empty 106 | tags: 107 | test: "tag" 108 | ``` 109 | 110 | ## Configuration options 111 | 112 | **Here is a detailed description of each of the SQS-specific options:** 113 | 114 | ### Prefetch 115 | 116 | `prefetch` - Number of jobs to prefetch from the SQS until ACK/NACK. 117 | Default: `10`. 118 | 119 | ### Visibility timeout 120 | 121 | `visibility_timeout` - The duration (in seconds) that the received messages are hidden from subsequent retrieve requests 122 | after being retrieved by a `ReceiveMessage` request. Max value is `43200` seconds (12 hours). Default: `0`. 123 | 124 | ### Wait time seconds 125 | 126 | `wait_time_seconds` - The duration (in seconds) for which the call waits for a message to arrive in the queue before 127 | returning. If a message is available, the call returns sooner than WaitTimeSeconds. If no messages are available and the 128 | wait time expires, the call returns successfully with an empty list of messages. 129 | 130 | Default: `5`. 131 | 132 | ### Queue 133 | 134 | `queue` - SQS internal queue name. Can contain alphanumeric characters, hyphens (`-`), and underscores (`_`). 135 | 136 | Default value is `default` string. 137 | 138 | ### Message Group ID 139 | 140 | `message_group_id` - Message group ID is required for FIFO queues. Messages that belong to the same message group are processed in a FIFO manner. 141 | More info: [link](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#SQS-SendMessage-request-MessageGroupId) 142 | 143 | ### Skip queue declaration 144 | 145 | `skip_queue_declaration` - By default, RR tries to declare the queue by default and then gets the queue URL. Set this 146 | option to `true` if the user already declared the queue to only get its URL. 147 | 148 | ### Consume all 149 | 150 | `consume_all` - By default, RR supports only `Jobs` structures from the queue. Set this option to true if you want to 151 | also consume the raw payloads. 152 | 153 | ### Attributes 154 | 155 | `attributes` - List of 156 | the [AWS SQS attributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html). 157 | 158 | ```yaml 159 | attributes: 160 | DelaySeconds: 0 161 | MaximumMessageSize: 262144 162 | MessageRetentionPeriod: 345600 163 | ReceiveMessageWaitTimeSeconds: 0 164 | VisibilityTimeout: 30 165 | ``` 166 | 167 | ### Tags 168 | 169 | `tags` - Tags don't have any semantic meaning. Amazon SQS interprets tags as character. 170 | 171 | > **Note** 172 | > This functionality is rarely used and slows down the work of 173 | > queues: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-queue-tags.html 174 | -------------------------------------------------------------------------------- /docs/en/releases/v2-12-0.md: -------------------------------------------------------------------------------- 1 | # Releases — v2.12.0 2 | 3 | # ⚠️ `websocket` and `broadcast` plugins was replaced by the new `centrifuge` plugin. 4 | 5 | # ⚠️ All plugins, `sdk` and `api` updated to `v3`. There are no breaking changes, we moved all Go code from the `api` to `sdk`. 6 | 7 | ##
👀 New:
8 | 9 | ###
RPC PLUGIN
10 | 11 | - ✏ New API to get the RR version and configuration in the JSON format -> `rpc.Version`, `rpc.Config`. 12 | 13 | ###
SERVICES PLUGIN
14 | 15 | - ✏ New API to get the correct number of the running services including statistic about the processes -> `server.Statuses`. 16 | - ✏ New option to show the service name in the logs 17 | 18 | ###
METRICS PLUGIN
19 | 20 | - ✏ New API unregister previously added collector -> `metrics.Unregister`. 21 | 22 | ###
AMQP PLUGIN
23 | 24 | - ✏ New configuration options: 25 | ```yaml 26 | jobs: 27 | pipelines: 28 | example: 29 | driver: amqp 30 | config: 31 | # Durable exchange 32 | # 33 | # Default: false 34 | exchange_durable: false 35 | 36 | # Auto-deleted exchange 37 | # 38 | # Default: false 39 | exchange_auto_deleted: false 40 | 41 | # Auto-deleted queue 42 | # 43 | # Default: false 44 | queue_auto_deleted: false 45 | ``` 46 | 47 | ###
GO-SDK
48 | 49 | - ✏ New option to control the `reset_timeout`: 50 | 51 | ```yaml 52 | pool: 53 | allocate_timeout: 10s 54 | reset_timeout: 10s 55 | destroy_timeout: 10s 56 | ``` 57 | 58 | ###
CENTRIFUGO PLUGIN
59 | 60 | - ✏ New `centrifugo` plugin. 61 | **Docs**: [PHP-lib](https://github.com/roadrunner-php/centrifugo) 62 | 63 | RoadRunner config: 64 | 65 | ```yaml 66 | version: "3" 67 | 68 | centrifuge: 69 | # Centrifugo server proxy address (docs: https://centrifugal.dev/docs/server/proxy#grpc-proxy) 70 | # 71 | # Optional, default: tcp://127.0.0.1:30000 72 | proxy_address: "tcp://127.0.0.1:30000" 73 | 74 | # gRPC server API address (docs: https://centrifugal.dev/docs/server/server_api#grpc-api) 75 | # 76 | # Optional, default: tcp://127.0.0.1:30000. Centrifugo: `grpc_api` should be set to true and `grpc_port` should be the same as in the RR's config. 77 | grpc_api_address: tcp://127.0.0.1:30000 78 | 79 | # Use gRPC gzip compressor 80 | # 81 | # Optional, default: false 82 | use_compressor: true 83 | 84 | # Your application version 85 | # 86 | # Optional, default: v1.0.0 87 | version: "v1.0.0" 88 | 89 | # Your application name 90 | # 91 | # Optional, default: roadrunner 92 | name: "roadrunner" 93 | 94 | # TLS configuration 95 | # 96 | # Optional, default: null 97 | tls: 98 | # TLS key 99 | # 100 | # Required 101 | key: /path/to/key.pem 102 | 103 | # TLS certificate 104 | # 105 | # Required 106 | cert: /path/to/cert.pem 107 | 108 | 109 | # Workers pool settings. link: https://github.com/roadrunner-server/roadrunner/blob/master/.rr.yaml#L812 110 | # 111 | # Optional, default: null (see default values) 112 | pool: {} 113 | ``` 114 | 115 | ###
APP-LOGGER PLUGIN
116 | 117 | - ✏ Application logger plugin. 118 | **Docs**: [PHP-lib](https://github.com/roadrunner-php/app-logger) 119 | 120 | 121 | ###
🩹 Fixes:
122 | 123 | - 🐛 **Headers middleware**: Header size is too small 124 | - 🐛 **gRPC plugin**: Protobuf compiler plugin segfaults on import statements 125 | - 🐛 **Service plugin**: Get services list via RPC 126 | - 🐛 **gRPC plugin**: Remote `protoc-gen-php-grpc` plugin error 127 | - 🐛 **HTTP plugin**: Fail to upload files when RR's permissions are different from worker's 128 | -------------------------------------------------------------------------------- /docs/en/releases/v2-12-1.md: -------------------------------------------------------------------------------- 1 | # Releases — v2.12.1 2 | 3 | ##
🚀 v2.12.1 🚀
4 | 5 | ##
👀 New:
6 | 7 | - ✏ **RR:** Automatically set the `GOMAXPROCS` to match the container CPU quota. 8 | - ✏ **AMQP plugin:** implement `Status` to check the AMQP connection [PR](https://github.com/roadrunner-server/amqp/pull/33). 9 | - ✏ **SQS plugin:** `prefetch` option now works as expected. RR will not consume new JOBS when it reaches the `prefetch` limit, until already accepted messages are not ACK/NACK-ed. 10 | - ✏ **JOBS(memory) plugin:** `prefetch` option now works as expected (see SQS). You can now emulate FIFO in memory by setting the `prefetch` option to 1. 11 | 12 | ###
🩹 Fixes:
13 | 14 | - 🐛 **gRPC plugin**: server options are applied only when TLS is set. [Discussion](https://github.com/roadrunner-server/roadrunner/discussions/1384). 15 | - 🐛 **AMQP plugin**: fix a few typos in the configuration. -------------------------------------------------------------------------------- /docs/en/releases/v2-12-2.md: -------------------------------------------------------------------------------- 1 | # Releases — v2.12.2 2 | 3 | ##
👀 New:
4 | 5 | - ✒️ **AMQP plugin:** Custom headers in AMQP driver, [FR](https://github.com/roadrunner-server/roadrunner/issues/1388), (thanks @ykweb) 6 | - ✒️ **AMQP plugin:** do not create a queue if the user does not consume it, [FR](https://github.com/spiral/roadrunner-jobs/issues/30), (thanks @Colomix) 7 | - ✒️ **gRPC plugin:** support additional metrics: `requests_queue`, `request_duration_seconds` and `request_total`, [PR](https://github.com/roadrunner-server/grpc/pull/62), docs: [link](https://roadrunner.dev/docs/app-server-grpc/2.x/en), (thanks @cv65kr) 8 | 9 | ###
🩹 Fixes:
10 | 11 | - 🐛 **Velox**: Unable to build RoadRunner with custom velox configuration, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1400), (thanks @mprokocki) 12 | - 🐛 **RR**: JSON Schema - wrong type for service `exec_timeout` option, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1410), (thanks @Chi-teck) 13 | - 🐛 **RR**: Fix the description of the `--silent` flag, [PR](https://github.com/roadrunner-server/roadrunner/pull/1401), (thanks @maximal) 14 | - 🐛 **X-Sendfile middleware:** make it work as expected (as the response header), [BUG](https://github.com/roadrunner-server/roadrunner/issues/1386), (thanks @tux-rampage) 15 | 16 | Special thanks: @benalf 17 | -------------------------------------------------------------------------------- /docs/en/releases/v2-12-3.md: -------------------------------------------------------------------------------- 1 | # Releases — v2.12.3 2 | 3 | ##
👀 New:
4 | 5 | - ✒️ **Composer.json:** add contributors, funds, project description: [PR](https://github.com/roadrunner-server/roadrunner/pull/1451), (thanks @roxblnfk) 6 | 7 | 8 | ###
🧹 Chore:
9 | 10 | - 🧑‍🏭 **Dependencies**: update project dependencies. 11 | - 🧑‍🏭 **Go**: update Go to `1.20`. 12 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-1-0.md: -------------------------------------------------------------------------------- 1 | # Releases — v2023.1.0 2 | 3 | ## ⚠️ The `reload` plugin has been removed from the default plugins list. Please use `*.pool.debug=true` instead. 4 | 5 | ## 👀 New 6 | 7 | - ✒️ **Kafka plugin:** Completely rewritten Kafka plugin. Now supports regexps for topics, marked commits for group consumers, and SASL authentication. Configuration reference: [link](https://roadrunner.dev/docs/plugins-jobs/2.x/en#kafka-driver). 8 | - ✒️ **RPC plugin:** The RPC plugin would be available immediately before worker initialization. This means that PHP worker can use all RPC methods immediately. 9 | - ✒️ Endure v2 support (internal change). 10 | - ✒️ Bash script to download the latest RR archive. Later we'll release a non-archived binary in addition to the regular archived releases. Sample of usage: 11 | ```bash 12 | curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/roadrunner-server/roadrunner/master/download-latest.sh | sh 13 | ``` 14 | - ✒️ RoadRunner Composer metapackage: Removed the `require` section: [PR](https://github.com/roadrunner-server/roadrunner/pull/1422), (thanks @roxblnfk) 15 | - ✒️ **Lock plugin:** New plugin to handle shared resource access. PHP client is a WIP with documentation. !!!!!! 16 | - ✒️ **AMQP plugin:** RR passes the queue, pipeline, and driver names to the PHP client in all modes, including the consuming payloads from the other senders. 17 | - ✒️ **AMQP plugin:** `consumer_id` can now be set in configuration, [FR](https://github.com/roadrunner-server/roadrunner/issues/1432), (thanks @codercms) 18 | - ✒️ **AMQP plugin:** Since `v2023.1.0` RR did not accept the empty queue name, [CH](https://github.com/roadrunner-server/roadrunner/issues/1443) 19 | - ✒️ **OTEL plugin:** ️Support OpenTelemetry for the `temporal`, `http`, `gRPC` and `Jobs` plugins, including all `Jobs` drivers. 20 | - ✒️ **Config plugin:** Configuration version updated to `version: '3'`. ️ 21 | - ✒️ **Logger plugin:** Now uses UTC timestamps [CH](https://github.com/roadrunner-server/roadrunner/issues/1442), (thanks @cv65kr) 22 | - ✒️ **Service plugin:** Instead of `SIGKILL`, send `SIGINT` with a 5s timeout to stop the underlying processes. 23 | - ✒️ **Configuration plugin:** Support for bash syntax with default values for keys. Starting from this release, you can use the following variables anywhere (values) in the configuration: `${LOG-LEVEL:-debug}`. That is, if the `LOG-LEVEL` env variable is not set, use `debug`. 24 | - ✒️ **gRPC plugin:** Support for custom interceptors. Will be generally available in the `2023.2.0`. 25 | - ✒️ **Temporal plugin:** Support for custom interceptors. Will be generally available in the `2023.2.0`. 26 | 27 | ## 🩹 Fixes 28 | 29 | - 🐛 **HTTP plugin**: Edge case where empty form value overwrites existing value, [PR](https://github.com/roadrunner-server/http/pull/87), (thanks @tungfinblox). 30 | - 🐛 **AMQP plugin**: Redial failed if user only uses consumer, [PR](https://github.com/roadrunner-server/roadrunner/issues/1472), (thanks @iborysenko). 31 | - 🐛 **RR CLI**: ./rr jobs` command panics when used without arguments, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1479), (thanks @embargo2710) 32 | - 🐛 **gRPC Plugin:** panic when calling `grpc.Workers` immediately after RR start.[BUG](https://github.com/roadrunner-server/roadrunner/issues/1532), (thanks @genhoi) 33 | - 🐛 **Proxy IP parser middleware:** Correctly handle the proxy headers from CloudFlare: [Discussion](https://github.com/orgs/roadrunner-server/discussions/1516), (thanks @victor-sudakov, @vladimir-vv) 34 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-1-1.md: -------------------------------------------------------------------------------- 1 | # Releases — v2023.1.1 2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **Centrifuge plugin**: Fix incorrect proto package import that caused panic on large payload. 6 | - 🐛 **PHP meta-package**: Unable to install RoadRunner via Composer, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1540), (thanks @monkenWu, @butschster) 7 | - 🐛 **HTTP plugin**: Fix double unmarshal of the main plugin configuration. 8 | - 🐛 **RR**: Fix `TestCommandWorkingDir` predefined temp directory, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1545), (thanks @shyim) 9 | - 🐛 **Status plugin**: Fix `superfluous response.WriteHeader` bug, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1544), (thanks @mfadul24) 10 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-1-2.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.1.2 🚀
2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **SQS plugin**: Revert optimized check for the AWS environment, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1550) 6 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-1-3.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.1.3 🚀
2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **AMQP plugin**: Driver crash when not using OTEL metrics: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1553), (thanks @rauanmayemir) 6 | - 🐛 **JOBS plugin**: Incorrect parsing of JSON configuration values: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1557), (thanks @embargo2710) 7 | 8 | ###
🧹 Chore:
9 | 10 | - 🧑‍🏭 **Dependencies**: update project dependencies. 11 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-1-4.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.1.4 🚀
2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **gRPC plugin**: allow specifying wildcards in the `proto` field: [PR](https://github.com/roadrunner-server/grpc/pull/90), (thanks @MaxSem) 6 | - 🐛 **SDK (internal)**: Workers are killed during processing when memory usage is exeeded: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1561), (thanks @ekisu) 7 | - 🐛 **JOBS plugin**: Jobs plugin hangd on many workers and pollers: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1568), (thanks @embargo2710) 8 | - 🐛 **JOBS plugin**: Safe shutdown occurs before the specified time: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1567), (thanks @embargo2710) 9 | - 🐛 **AMQP plugin**: Typo in the property name (`multiple_ack`): [BUG](https://github.com/roadrunner-server/roadrunner/issues/1565), (thanks @embargo2710) 10 | 11 | ###
🧹 Chore:
12 | 13 | - 🧑‍🏭 **Dependencies**: update project dependencies. 14 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-1-5.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.1.5 🚀
2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **KV plugin**: Correct plugin startup order: [PR](https://github.com/roadrunner-server/roadrunner/issues/1589), (thanks @ekisu) 6 | - 🐛 **JOBS plugin**: Check the pool pointer: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1597), (thanks @Kaspiman) 7 | - 🐛 **Send Middleware**: Fix bug in http.ResponseWriter wrapper: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1593), (thanks @tux-rampage) 8 | 9 | ## 👀 New 10 | 11 | - ✒️ **Docker** Add tags with minor version (e.g.: `v2023.1`, `v2023.2`, etc.): [FR](https://github.com/roadrunner-server/roadrunner/issues/1581), (thanks @Kaspiman) 12 | 13 | ###
🧹 Chore:
14 | 15 | - 🧑‍🏭 **Dependencies**: update project dependencies. 16 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-2-0.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.2.0 🚀
2 | 3 | ## 👀 New 4 | 5 | - ✒️ **Kafka driver**: Support for the `SCRAM-SHA-256` and `SCRAM-SHA-512` SASL mechanisms: [FR](https://github.com/roadrunner-server/roadrunner/issues/1601), (thanks @Azomas) 6 | - ✒️ **Headers middleware**: Actualize CORS support: [FR](https://github.com/roadrunner-server/roadrunner/issues/909), (thanks @rmikalkenas, @hustlahusky) 7 | - ✒️ **RoadRunner CLI**: Additional [semgrep](https://semgrep.dev/) security scanner. 8 | - ✒️ **Docker builds**: New tags: `v2023`, `v2023.x` and with bugfix: `v2023.x.x`. The `latest` tag points to the latest **stable** release. All `rc`, `beta`, `alpha` releases will no longer be tagged with `latest`. 9 | - ✒️ **AMQP driver**: Support for the `TLS` transport named `amqps`: [FR](https://github.com/roadrunner-server/roadrunner/issues/1538), (thanks @marcosraudkett) 10 | - ✒️ **JOBS plugin**: Support for the worker health/readiness checks. [PR](https://github.com/roadrunner-server/jobs/pull/81), (thanks @Kaspiman) 11 | - ✒️ **JOBS plugin**: Delete all messages that were in the priority queue when the pipeline was deleted (1-st part of the BUG), [BUG](https://github.com/roadrunner-server/roadrunner/issues/1382) 12 | - ✒️ **JOBS plugin**: JOBS plugin now support reporting its worker status with a simple query: `http://:/ready(health)?plugin=jobs`, [PR](https://github.com/roadrunner-server/roadrunner/issues/1382), (thanks @Kaspiman) 13 | - ✒️ **Temporal plugin, internal**: Pass `history_len` to the PHP worker and get the PHP-SDK version to pass to the Temporal server. 14 | - ✒️ **Lock plugin**: Completely rewritten. Now supports a microsecond interval. Any `ttl/wait_ttl` value passed to RR is now treated as **microseconds**. There is no configuration for this plugin, it is bundled with RR. 15 | - ✒️ **Service plugin**: Add a new option for the graceful process timeout: `timeout_stop_sec`. RR will wait for the specified amount of time (but not more than `endure.graceful_period`) for the process to stop, [FR](https://github.com/roadrunner-server/roadrunner/issues/1628), (thanks @asanikovich) 16 | 17 | ## 🩹 Fixes 18 | 19 | - 🐛 **JOBS plugin**: Nil pointer exception on very fast (after RR was started, but JOBS worker failed to start) check for the JOBS metrics: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1597), (thanks @Kaspiman). 20 | - 🐛 **Service plugin**: Incorrect parsing and assignment of the `process_num` value passed via RPC: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1621), (thanks @asanikovich) 21 | 22 | ###
🧹 Chore:
23 | 24 | - 🧑‍🏭 **Dependencies**: update project dependencies. 25 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-2-1.md: -------------------------------------------------------------------------------- 1 | ## Description of Changes 2 | 3 | #
🚀 v2023.2.1 🚀
4 | 5 | ## 🩹 Fixes 6 | 7 | - 🐛 **NATS driver**: Segfault when sending job via third-party sender without `consume_all` option set to `true`: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1650), (thanks @KernelMrex). 8 | - 🐛 **Metrics plugin**: Irregular panic when declaring metrics via `on_init` option: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1648), (thanks @Kaspiman). 9 | - 🐛 **Headers middleware**: Inconsistent usage of CORS options, failed to apply `allowed_*` options with spaces: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1655), (thanks @gam6itko). 10 | 11 | ###
🧹 Chore:
12 | 13 | - 🧑‍🏭 **Dependencies**: update project dependencies. 14 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-2-2.md: -------------------------------------------------------------------------------- 1 | ## Description of Changes 2 | 3 | #
🚀 v2023.2.2 🚀
4 | 5 | ## 🩹 Fixes 6 | 7 | - 🐛 **JOBS plugin**: Fix typo in the `RPC` span name: [PR](https://github.com/roadrunner-server/jobs/pull/92), (thanks @Kaspiman). 8 | - 🐛 **SDK**: Fix incorrect workers state when worker reached `idleTTL` state: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1669), (thanks @Aleksa1996). 9 | 10 | ###
🧹 Chore:
11 | 12 | - 🧑‍🏭 **HTTP plugin**: faster PostForm/MultipartForm processing [PR](https://github.com/roadrunner-server/http/pull/145). 13 | - 🧑‍🏭 **Golang**: Update Golang version to v1.21. 14 | - 🧑‍🏭 **Dependencies**: update project dependencies. 15 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-0.md: -------------------------------------------------------------------------------- 1 | ## Description of Changes 2 | 3 | #
🚀 v2023.3.0 🚀
4 | 5 | ## 🔥 Features: 6 | 7 | ### RR Core: 8 | 9 | - ✒️ `sdnotify` support: [FR](https://github.com/roadrunner-server/roadrunner/pull/1671), (thanks @Kaspiman), Docs: [link](https://roadrunner.dev/docs/app-server-systemd/current/en) 10 | - ✒️ Dynamic worker scaling: [FR](https://github.com/roadrunner-server/roadrunner/issues/1728), (thanks @butschster), Docs: [link](https://roadrunner.dev/docs/php-scaling/current/en) 11 | 12 | ## 👀 JOBS plugin: 13 | 14 | - ✒️ **AMQP Driver:** Support for a custom `routing_key` in the JOBS payload: [FR](https://github.com/roadrunner-server/roadrunner/issues/1555), (thanks @rauanmayemir) 15 | - ✒️ **JOBS plugin**: Parallel pipelines start/stop/destroy initialization. If you have much number of the pipelines, 16 | this feature should significantly reduce RR startup/shutdown time: [FR](https://github.com/roadrunner-server/roadrunner/issues/1672), (thanks @Kaspiman) 17 | 18 | ## 👀 KV drivers (all): 19 | 20 | - ✒️ Support for OTEL across all KV drivers: [FR](https://github.com/roadrunner-server/roadrunner/issues/1635) 21 | 22 | ## 👀 App-Logger plugin: 23 | 24 | - ✒️ Added new methods for your logger to log with context (message + key-values array): [FR](https://github.com/roadrunner-server/roadrunner/issues/1633), (thanks @Baiquette) 25 | 26 | ## 👀 Temporal plugin: 27 | 28 | - ✒️ Replay API support [SINCE PHP-SDK 2.6.0]: [FR](https://github.com/roadrunner-server/roadrunner/issues/1640) 29 | - ✒️ Add support for the Worker Versioning: [FR](https://github.com/roadrunner-server/roadrunner/issues/1689) 30 | 31 | ## 👀 Service plugin: 32 | 33 | - ✒️ Support for the user/group per-service: [FR](https://github.com/roadrunner-server/roadrunner/issues/1570), (thanks @Kaspiman) 34 | #### Configuration example: 35 | ```yaml 36 | service: 37 | schedule:run: 38 | command: "bin/console schedule:run" 39 | process_num: 1 40 | exec_timeout: 0s 41 | remain_after_exit: true 42 | service_name_in_log: false 43 | restart_sec: 60 44 | user: www-data # <---------- [NEW] 45 | group: www-data # <---------- [NEW] 46 | ``` 47 | 48 | ## 👀 HTTP plugin: 49 | 50 | - ✒️ Response streaming support [FR](https://github.com/roadrunner-server/http/pull/152), (thanks @roxblnfk) 51 | 52 | Worker example: 53 | 54 | ```php 55 | 56 | waitRequest()) { 80 | $http->respond(200, $read()); 81 | } 82 | } catch (\Throwable $e) { 83 | $worker->error($e->getMessage()); 84 | } 85 | ``` 86 | 87 | - ✒️ Support for the `103` Early Hints via streamed response: [FR](https://github.com/roadrunner-server/roadrunner/issues/918), (thanks @azjezz) 88 | 89 | Worker example: 90 | 91 | ```php 92 | waitRequest()) { 122 | $http->respond(103, '', headers: ['Link' => ['; rel=preload; as=style'], 'X-103' => ['103']], endOfStream: false); 123 | $http->respond(200, $read(), headers: ['X-200' => ['200']], endOfStream: true); // your regular response 124 | } 125 | } catch (\Throwable $e) { 126 | $worker->error($e->getMessage()); 127 | } 128 | ``` 129 | 130 | ## 👀 Server plugin: 131 | 132 | - ✒️ **RAW command support**: Support for raw commands, which are not validated by RR and may contain spaces. Note that this feature is only supported via `.rr.yaml` configuration: [FR](https://github.com/roadrunner-server/roadrunner/issues/1667), (thanks @nunomaduro) 133 | First argument should be a command (executable) and the rest of the arguments are passed to the command as arguments. 134 | 135 | ```yaml 136 | version: "3" 137 | 138 | server: 139 | command: ["php", "../../php_test_files/client.php echo pipes"] 140 | relay: "pipes" 141 | relay_timeout: "20s" 142 | ``` 143 | 2. 144 | ```yaml 145 | version: "3" 146 | 147 | server: 148 | command: 149 | - "php" 150 | - "../../php_test_files/client.php echo pipes" 151 | relay: "pipes" 152 | relay_timeout: "20s" 153 | ``` 154 | 155 | ## 🩹 Fixes: 156 | 157 | - 🐛 **RR Core**: Actualize, according to the docs `./rr jobs list/stop/resume` commands: [PR](https://github.com/roadrunner-server/roadrunner/pull/1675), (thanks @gam6itko). 158 | - 🐛 **JOBS plugin**: Correctly handle OTEL span on listener error: [PR](https://github.com/roadrunner-server/amqp/pull/87), (thanks @Kaspiman). 159 | - 🐛 **RR tests**: Fix test failures on Darwin: [PR](https://github.com/roadrunner-server/roadrunner/pull/1680), (thanks @shyim). 160 | - 🐛 **Streaming**: Add stream timeout (will be configurable in the next release). Fix loss of the first chunk of the streamed response. 161 | 162 | 163 | ###
🧹 Chore:
164 | - 🧑‍🏭 **Golang**: Update Golang version to v1.21. 165 | - 🧑‍🏭 **Dependencies**: update project dependencies. 166 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-1.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.1 [Maintenance release] 🚀
2 | 3 | ###
🧹 Chore:
4 | 5 | - 🧑‍🏭 **Dependencies**: update project dependencies (including CVE in Go libraries). 6 | - 🧑‍🏭 **Go**: Update Golang to version 1.21.3. 7 | - 🧑‍🏭 **Docs**: Missed documentation about Dynamic Workers Scaling: [link](https://roadrunner.dev/docs/php-scaling/current/en) -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-2.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.2 [Maintenance] 🚀
2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **Temporal**: Fix incorrect log entry: [ISSUE](https://github.com/roadrunner-server/roadrunner/issues/1752) 6 | 7 | 8 | ###
🧹 Chore:
9 | 10 | - 🧑‍🏭 **Dependencies**: update project dependencies (including CVE in transitive dependencies, especially gofiber). -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-3.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.3 [Bugfix] 🚀
2 | 3 | ## 🩹 Fixes 4 | 5 | - 🐛 **RR Core**: Fix mistakenly removed RPC endpoint: [ISSUE](https://github.com/roadrunner-server/roadrunner/issues/1758) -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-4.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.4 🚀
2 | 3 | ## 🔥 Features: 4 | 5 | ### RR Core: 6 | 7 | - ✒️ **Experimental features:** Add support for the experimental features: [Docs](https://roadrunner.dev/docs/experimental-experimental/current/en). 8 | 9 | ## 👀 Plugins: 10 | 11 | - ✒️ **NATS driver:** Replace the old JetStream client with the new one: [FR](https://github.com/roadrunner-server/roadrunner/issues/1574), [API](https://github.com/nats-io/nats.go/blob/main/jetstream/README.md). 12 | - ✒️ **Config driver:** Add experimental support for merging two and more configuration files: [FR](https://github.com/roadrunner-server/roadrunner/issues/935), [Docs](https://roadrunner.dev/docs/experimental-experimental/current/en) 13 | - ✒️ **Headers middleware:** Add support for the regular expressions for `origin`: [FR](https://github.com/roadrunner-server/roadrunner/issues/1709), [Docs](https://roadrunner.dev/docs/http-headers/current/en#cors) 14 | 15 | ## 🩹 Fixes 16 | 17 | - 🐛 **HTTP Plugin**: Unable to POST relatively chunky POST: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1765) -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-5.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.5 🚀
2 | 3 | ### Config plugin: 4 | 5 | - 🔥 Add the ability to include `.env` files in the configuration (experimental feature): [Docs](https://roadrunner.dev/docs/experimental-experimental/current/en#support-for-loading-envfiles-in-the-rryaml--v202335) 6 | 7 | ### Temporal plugin: 8 | 9 | - 🐛️ Fix bug with incorrect pool destroy order: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1776) 10 | 11 | ### HTTP plugin: 12 | 13 | - 🔥 Allow showing PHP exception traces in the response: [BUG](https://github.com/roadrunner-server/roadrunner/issues/1781) 14 | 15 | 16 | #
🧹 Chore:
17 | 18 | - 🧑‍🏭 **Dependencies**: update project (system) dependencies. -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-6.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.6 🚀
2 | 3 | ### CI releases: 4 | 5 | - 🔥 Add support for the `arm64` deb packages: [FR](https://github.com/roadrunner-server/roadrunner/issues/1785) 6 | 7 | ###
🧹 Chore:
8 | 9 | - 🧑‍🏭 **Dependencies**: update project/system dependencies. -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-7.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.7 🚀
2 | 3 | ### `gRPC` plugin: 4 | 5 | - 🔥 Re-enable HTTP health and readiness checks via regular endpoints `/health` and `/ready`. 6 | 7 | ### `AMQP` driver: 8 | 9 | - 🐛️ Fix mapping for the RabbitMQ type `List` (Golang `[]any`), [BUG](https://github.com/roadrunner-server/roadrunner/issues/1793) 10 | - 🐛️ Fix an edge case for the DLX queue type when user doesn't specify any queue, but use `Push` method with delays, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1792) 11 | 12 | ###
🧹 Chore:
13 | 14 | - 🧑‍🏭 **Dependencies**: update project/system dependencies. -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-8.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.8 🚀
2 | 3 | ### `HTTP` plugin 4 | 5 | - 🔥 Experimental HTTP3 server, [FR](https://github.com/roadrunner-server/roadrunner/issues/926), docs: [link](https://roadrunner.dev/docs/experimental-experimental/current/en#support-for-the-http3-server-202338), (thanks @cv65kr & @cidious) 6 | 7 | ### `gRPC` plugin 8 | 9 | - 🔥 Experimental support for the OTLP protocol inside the `gRPC` plugin: [FR](https://roadrunner.dev/docs/experimental-experimental/current/en#otlp-support-in-the-grpc-plugin-202338), (thanks @rauanmayemir) 10 | 11 | ### `Beanstalk` driver 12 | 13 | - 🐛️ Fix NPE on empty options [BUG](https://github.com/roadrunner-server/roadrunner/issues/1804), (thanks @SerhiiMova). 14 | 15 | ### `Velox` plugin 16 | 17 | - 🔥 To ensure that Velox is able to build every RoadRunner version, we've added a new CI CRON job that builds RoadRunner with Velox daily. This job is not related to the RoadRunner release process, but it will help us to ensure that Velox is always compatible with the latest RoadRunner version. 18 | 19 | ###
🧹 Chore:
20 | 21 | - 🧑‍🏭 **Dependencies**: update project/system dependencies. 22 | -------------------------------------------------------------------------------- /docs/en/releases/v2023-3-9.md: -------------------------------------------------------------------------------- 1 | #
🚀 v2023.3.9 🚀
2 | 3 | ### `HTTP` plugin 4 | 5 | - 🐛️ Streaming responses can experience a lock-up when the client disconnects early, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1830), (thanks @segrax) 6 | 7 | ### `SQS` JOBS driver 8 | 9 | - 🐛️ Use user specified credentials if they are set even if we're inside AWS, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1833), (thanks @matteokov) 10 | 11 | ### `Service` plugin 12 | 13 | - 🐛️ Services directly killed when restarting on terminating. [BUG](https://github.com/roadrunner-server/roadrunner/issues/1814), (thanks @chazzbg) 14 | 15 | ### `Server` plugin 16 | 17 | - 🔥 Add `user` param to `on_init` command section. [PR](https://github.com/roadrunner-server/server/pull/68), [docs](https://roadrunner.dev/docs/plugins-server/current/en#configuration), (thanks @Kaspiman) 18 | 19 | ### `Redis` KV driver 20 | 21 | - 🐛️ Correctly finish the OTEL span. [PR](https://github.com/roadrunner-server/redis/pull/62), (thanks @Kaspiman) 22 | 23 | ###
🧹 Chore:
24 | 25 | - 🧑‍🏭 **Dependencies**: update project/system dependencies. 26 | - 🧑‍🏭 **Docs**: update docs, [BUG](https://github.com/roadrunner-server/roadrunner/issues/1819). 27 | -------------------------------------------------------------------------------- /docs/en/resources/kv-general-info.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrunner-server/roadrunner-docs/ebc8118becc3e3a1dafe4bfc303c0eeee2ff44bd/docs/en/resources/kv-general-info.psd -------------------------------------------------------------------------------- /docs/en/resources/queue-general-info.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrunner-server/roadrunner-docs/ebc8118becc3e3a1dafe4bfc303c0eeee2ff44bd/docs/en/resources/queue-general-info.psd -------------------------------------------------------------------------------- /docs/en/resources/queue-rr-env-mode.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roadrunner-server/roadrunner-docs/ebc8118becc3e3a1dafe4bfc303c0eeee2ff44bd/docs/en/resources/queue-rr-env-mode.psd -------------------------------------------------------------------------------- /docs/en/workflow/temporal.md: -------------------------------------------------------------------------------- 1 | # About Temporal.IO 2 | Temporal is a distributed, scalable, durable, and highly available orchestration engine used to execute asynchronous 3 | long-running business logic in a scalable and resilient way. 4 | 5 | Read more at [official website](https://docs.temporal.io/). 6 | 7 | RoadRunner >= 2.0 includes a plugin to execute Temporal workflows and activities. Make sure to write [temporal worker](worker.md). 8 | 9 | Activate plugin via config: 10 | 11 | ```yaml 12 | rpc: 13 | listen: tcp://127.0.0.1:6001 14 | 15 | server: 16 | command: "php worker.php" 17 | 18 | temporal: 19 | address: "127.0.0.1:7233" 20 | activities: 21 | num_workers: 10 22 | 23 | logs: 24 | level: debug 25 | channels: 26 | temporal.level: error 27 | ``` 28 | 29 | ## Example 30 | Integrated workflow server provides the ability to create very complex, long-running activities. 31 | 32 | ```php 33 | class SubscriptionWorkflow implements SubscriptionWorkflowInterface 34 | { 35 | private $account; 36 | 37 | public function __construct() 38 | { 39 | $this->account = Workflow::newActivityStub( 40 | AccountActivityInterface::class, 41 | ActivityOptions::new() 42 | ->withScheduleToCloseTimeout(DateInterval::createFromDateString('2 seconds')) 43 | ); 44 | } 45 | 46 | public function subscribe(string $userID) 47 | { 48 | yield $this->account->sendWelcomeEmail($userID); 49 | 50 | try { 51 | $trialPeriod = true; 52 | while (true) { 53 | // Lower period duration to observe workflow behavior 54 | yield Workflow::timer(DateInterval::createFromDateString('30 days')); 55 | yield $this->account->chargeMonthlyFee($userID); 56 | 57 | if ($trialPeriod) { 58 | yield $this->account->sendEndOfTrialEmail($userID); 59 | $trialPeriod = false; 60 | continue; 61 | } 62 | 63 | yield $this->account->sendMonthlyChargeEmail($userID); 64 | } 65 | } catch (CanceledFailure $e) { 66 | yield Workflow::asyncDetached( 67 | function () use ($userID) { 68 | yield $this->account->processSubscriptionCancellation($userID); 69 | yield $this->account->sendSorryToSeeYouGoEmail($userID); 70 | } 71 | ); 72 | } 73 | } 74 | } 75 | ``` 76 | 77 | > Read more at [official website](https://docs.temporal.io/application-development?lang=php). 78 | -------------------------------------------------------------------------------- /docs/en/workflow/worker.md: -------------------------------------------------------------------------------- 1 | # Temporal Worker 2 | Unlike HTTP, Temporal use different way to configure a worker. Make sure to require PHP SDK: 3 | 4 | ``` 5 | $ composer require temporal/sdk 6 | ``` 7 | 8 | The worker file will look as following: 9 | 10 | ```php 11 | newWorker( 25 | 'taskQueue', 26 | \Temporal\Worker\WorkerOptions::new()->withMaxConcurrentActivityExecutionSize(10) 27 | ); 28 | 29 | // Workflows are stateful. So you need a type to create instances. 30 | $worker->registerWorkflowTypes(MyWorkflow::class); 31 | 32 | // Activities are stateless and thread safe. So a shared instance is used. 33 | $worker->registerActivityImplementations(new MyActivity()); 34 | 35 | 36 | // start primary loop 37 | $factory->run(); 38 | ``` 39 | 40 | Read more about temporal configuration and usage [at official website](https://docs.temporal.io/application-development/features). 41 | 42 | ## Multi-worker Environment 43 | To serve both HTTP and Temporal from the same worker use `getMode()` option of `Environment`: 44 | 45 | ```php 46 | use Spiral\RoadRunner; 47 | 48 | $rrEnv = RoadRunner\Environment::fromGlobals(); 49 | 50 | if ($rrEnv->getMode() === RoadRunner\Environment\Mode::MODE_TEMPORAL) { 51 | // start temporal worker 52 | return; 53 | } 54 | 55 | if ($rrEnv->getMode() === RoadRunner\Environment\Mode::MODE_HTTP) { 56 | // start http worker 57 | return; 58 | } 59 | ``` 60 | 61 | Or you may override server's command via: 62 | ```yaml 63 | temporal: 64 | address: "127.0.0.1:7233" 65 | activities: 66 | num_workers: 10 67 | command: "php temporal.php" 68 | ``` 69 | -------------------------------------------------------------------------------- /languages.json: -------------------------------------------------------------------------------- 1 | { 2 | "en": "docs/en" 3 | } 4 | --------------------------------------------------------------------------------