Giter Site home page Giter Site logo

roadrunner-server / roadrunner Goto Github PK

View Code? Open in Web Editor NEW
7.7K 148.0 403.0 72.24 MB

๐Ÿคฏ High-performance PHP application server, process manager written in Go and powered with plugins

Home Page: https://roadrunner.dev

License: MIT License

Go 86.13% Makefile 0.17% Dockerfile 2.98% Shell 7.25% JavaScript 3.47%
application-server golang workers supervisor php psr-7 http rpc roadrunner

roadrunner's Introduction

All releases

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, process manager written in Go and powered with plugins โค๏ธ. It supports running as a service with the ability to extend its functionality on a per-project basis with plugins.

Features

RoadRunner features a range of plugins, including HTTP(S)/2/3 and fCGI servers that are compatible with PSR-7/PSR-17 standards. This is just one of its many capabilities. It serves as an effective alternative to the traditional Nginx+FPM setup, providing improved performance and more flexibility. Its extensive plugin options go far beyond just HTTP(S)/2/3 and fCGI servers, offering a broad range of functionalities:

  • Queue drivers: RabbitMQ, Kafka, SQS, Beanstalk, NATS, In-Memory.
  • KV drivers: Redis, Memcached, BoltDB, In-Memory.
  • OpenTelemetry protocol support (gRPC, http, jaeger).
  • Workflow engine via Temporal.
  • gRPC server. For increased speed, the protobuf extension can be used.
  • HTTP(S)/2/3 and fCGI servers features automatic TLS management, 103 Early Hints support and middleware like: Static, Headers, gzip, prometheus (metrics), send (x-sendfile), OTEL, proxy_ip_parser, etc.
  • Embedded distribute lock plugin which manages access to shared resources.
  • Metrics server (you might easily expose your own).
  • WebSockets and Broadcast via Centrifugo server.
  • Systemd-like services manager with auto-restarts, execution time limiter, etc.
  • Production-ready.
  • And more ๐Ÿ˜‰

Join our discord server: Link

Official Website | Documentation | Forum | Release schedule

Installation

The easiest way to get the latest RoadRunner version is to use one of the pre-built release binaries, which are available for OSX, Linux, FreeBSD, and Windows. Instructions for using these binaries are on the GitHub releases page.

Docker:

To get the roadrunner binary file you can use our docker image: ghcr.io/roadrunner-server/roadrunner:2024.X.X (more information about image and tags can be found here).

FROM ghcr.io/roadrunner-server/roadrunner:2024.X.X AS roadrunner
FROM php:8.3-cli

COPY --from=roadrunner /usr/bin/rr /usr/local/bin/rr

# USE THE RR

Configuration located in the .rr.yaml file (full sample):

Installation via Composer

You can also install RoadRunner automatically using the command shipped with the composer package, run:

composer require spiral/roadrunner-cli
./vendor/bin/rr get-binary

Server binary will be available at the root of your project.

Note

PHP's extensions php-curl and php-zip are required to download RoadRunner automatically. PHP's extensions php-sockets need to be installed to run roadrunner. Check with php --modules your installed extensions.

Installation option for the Debian-derivatives (Ubuntu, Mint, MX, etc)

wget https://github.com/roadrunner-server/roadrunner/releases/download/v2024.X.X/roadrunner-2024.X.X-linux-amd64.deb
sudo dpkg -i roadrunner-2024.X.X-linux-amd64.deb

Download the latest release via curl:

curl --proto '=https' --tlsv1.2 -sSf  https://raw.githubusercontent.com/roadrunner-server/roadrunner/master/download-latest.sh | sh

MacOS using Homebrew:

brew install roadrunner

Configuration can be located in .rr.yaml file (full sample):

version: '3'

rpc:
  listen: tcp://127.0.0.1:6001

server:
  command: "php worker.php"

http:
  address: "0.0.0.0:8080"

logs:
  level: error

Read more in Documentation.

Example Worker:

<?php

use Spiral\RoadRunner;
use Nyholm\Psr7;

include "vendor/autoload.php";

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

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

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

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

Important

If you see the EOF error, check that you have installed the PHP packages from this step. If this does not help, try to execute the command php worker.php directly and check the output.


Available Plugins: link

Run:

To run application server:

$ ./rr serve -c .rr.yaml

License:

The MIT License (MIT). Please see LICENSE for more information. Maintained by Spiral Scout.

Contributors

Thanks to all the people who already contributed!

roadrunner's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

roadrunner's Issues

Connections hangs under Windows

Windows 10
PHP 7.3.0
RR 1.3.0

Clean Symfony 4.2 Skeleton app.
Worker script is copied from here: https://github.com/spiral/roadrunner/wiki/Symfony-Framework with little path-related changes.
RR config:

# defines environment variables for all underlying php processes
env:
  key: value

http:
  address: :8090
  workers:
    command: "php src/RRBootstrap.php"
    pool:
      numWorkers: 4
      # maximum jobs per worker, 0 - unlimited.
      maxJobs:  0
      # for how long worker is allowed to be bootstrapped.
      allocateTimeout: 60
      # amount of time given to worker to gracefully destruct itself.
      destroyTimeout:  60

  # max POST request size, including file uploads in MB.
  maxRequest: 50

# static file serving. remove this section to disable static file serving.
static:
  # root directory for static file (http would not serve .php and .htaccess files).
  dir:   "public"

  # list of extensions for forbid for serving.
  forbid: [".php", ".htaccess"]

Console rr output:

>rr\rr serve -v -d
DEBU[0000] [rpc]: started
DEBU[0000] [http]: started

When I connect to the 8081 port, connections hangs and never ends. No response, no timeout errors. Right now I'm observing a 30-minute conection.

It seems there must be at least a timeout error. And I want to know how to debug and solve such a problem?

Native English speaker help is needed

English is not my first language and this weird extension for Chrome which checks grammar does now work in IDE or in the source editor.

I would appreciate if someone can help polish up README a bit.

For the love of god, why?

I used to use PHP and i now exclusively work with Go.

Dear developer, let PHP go the way of the dodo bird. It had a good run. This package makes my heart hurt.

[Feature Request] AccessLog

RR not have enough features to be complete web server for now.
The one of required is a access log.

My suggestions about access log feature:

  • included out of the box
  • configurable log format
  • support all fields of Apache Combined Log Format
  • support additional fields:
    • Custom headers (for example to print custom request id to track in logs)
    • The time taken to serve the request
    • Node name (/etc/hostname)
    • Environment variable
    • Worker ID (UUID?)
    • Worker execution count
    • Worker execution time
    • Worker memory usage

Config CLI flag seems to be ignored

I am trying to set the config file to a different location to where the roadrunner binary is located. When I add the config CLI flag, it seems to be ignored.

When I run:
vagrant@locahost:/$ /usr/bin/rr --config=/etc/roadrunner/.rr.yaml serve

I get the following output and the server stops:

WARN[0000] config: Config File ".rr" Not Found in "[/]"

How to run wordpress with this server?

This software looks very interesting and promising.
However, i didn't find some dock that explains how to use it with php apps .

For example, if i want to run wordpress with it. What should i do?
As i understand, i have to create a worker. But it is not clean what should be in that worker. Just require("wordpress/index.php") ?

Also, as i understand PHP must be installed separately. It is not part of this code. What are requirements for PHP intallation?
What are requirements fro PHP on different platforms?

My aim is to understand if i can use this tool to make a desktop version of my PHP application. I want to make installation package with my PHP code, some web server and PHP itself

[Feature Request] Worker fatal error handling

For now if worker crashed with fatal error the stack trace are print to browser.

I have several suggestions:

  • Prevent printing stack traces to browser
  • Add options to configure static html (or url request) for custom error page
  • Print stack trace to stderr
  • Implement raven-go and push errors to Sentry

No UserAgent set in $_SERVER when using PSR7Client

If you dump the contents of the $ctx and $_SERVER right before $this->configureServer($ctx) during acceptRequest() in PSR7Client.php to different files, you'll see that the context contains a "User-Agent" in its headers but its not yet set in the $_SERVER, which is fine.

However configureServer does not attempt to set the User_Agent and does not appear to set it anywhere else.

Adding

if(isset($ctx['headers']['User-Agent']))
            $server['HTTP_USER_AGENT'] = $ctx['headers']['User-Agent'][0];

to configureServer in the PSR7Client.php file fixes this issue.

example setup

IS there an example setup somewhere (that runs straight away?)

Wrong values for $_SERVER['REQUEST_TIME'] and $_SERVER['REQUEST_TIME_FLOAT']

Every request has the same value for $_SERVER['REQUEST_TIME'] (the timestamp of when the rr process started). $_SERVER['REQUEST_TIME_FLOAT'] is similar but the only for the seconds part, the milliseconds is always changing.

Some middleware rely on that value and will misbehave due to the wrong value, e.g.: https://github.com/middlewares/response-time/blob/0eb140f53365bcda5a88449fda29b818aa95c64a/src/ResponseTime.php#L18-L25

HTTPS Support

Any plans to support HTTPS connections? Preferably you can configure RoadRunner so that it supports both HTTP and HTTPS if desired.

A way to restart worker programmatically

The application should be able to send a specific response header to restart the worker or all.

This is needed for proxy classes which are changing in the runtime

Logging inside of Docker doesn't work

In a comment in #12, it came up that anything sent to STDERR should get relayed to Docker and displayed, but in my experience that's simply not the case. I've tried the following things, none of which work:

  • ini_set('display_errors', 'stderr');
  • fwrite(STDOUT, 'some message'); (this can crash the relay process, since it corrupts the packet format)
  • fwrite(STDERR, 'some message');

File-based logging works fine, but doesn't actually help without a tremendous amount of complexity (Docker is, generally speaking, watching the top-level process's STDOUT and STDERR).

The only logs I've been able to get (by using rr serve -v -d) are the access logs, and they get goofy formatting due to attempted colorization.

It would be immensely preferable if this worked the same way PHP-FPM does; i.e. STDOUT and STDERR "just work" (a random var_dump/exit debugger in a script won't disappear, etc), but I can't think of a good way to support this while keeping supports for sockets working. The pipes connection method could be adapted to make STDERR work as expected, but it wouldn't solve the STDOUT thing without quite a lot of work (I have a couple of napkin-quality ideas about this, but don't know Go too well)

How to try it?

I have .rr.yaml:

http:
  address: 0.0.0.0:8080
  workers:
    command: "php psr-worker.php"
    pool:
      numWorkers: 4

I've put the code of your example inside psr-worker.php:

<?php
ini_set('display_errors', 'stderr');
include "vendor/autoload.php";

$relay = new Spiral\Goridge\StreamRelay(STDIN, STDOUT);
$psr7 = new Spiral\RoadRunner\PSR7Client(new Spiral\RoadRunner\Worker($relay));


while ($req = $psr7->acceptRequest()) {
    try {
        $resp = new \Zend\Diactoros\Response();
        $resp->getBody()->write("hello world");

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

I installed composer. (but you dont have info about it)

I tried:

./rr serve -v -d

I have errors:

DEBU[0000] [static]: disabled
DEBU[0000] [rpc]: started
DEBU[0000] [http]: started
ERRO[0000] [http]: unable to connect to worker: PHP Warning: include(vendor/autoload.php): failed to open stream: No such file or directory in /var/www/test/roadrunner/psr-worker.php on line 3
PHP Stack trace:
PHP 1. {main}() /var/www/test/roadrunner/psr-worker.php:0

Warning: include(vendor/autoload.php): failed to open stream: No such file or directory in /var/www/test/roadrunner/psr-worker.php on line 3

Call Stack:
0.0001 400184 1. {main}() /var/www/test/roadrunner/psr-worker.php:0

PHP Warning: include(): Failed opening 'vendor/autoload.php' for inclusion (include_path='.:/usr/share/php') in /var/www/test/roadrunner/psr-worker.php on line 3
PHP Stack trace:
PHP 1. {main}() /var/www/test/roadrunner/psr-worker.php:0

Warning: include(): Failed opening 'vendor/autoload.php' for inclusion (include_path='.:/usr/share/php') in /var/www/test/roadrunner/psr-worker.php on line 3

Call Stack:
0.0001 400184 1. {main}() /var/www/test/roadrunner/psr-worker.php:0

PHP Fatal error: Uncaught Error: Class 'Spiral\Goridge\StreamRelay' not found in /var/www/test/roadrunner/psr-worker.php:5
Stack trace:
#0 {main}
thrown in /var/www/test/roadrunner/psr-worker.php on line 5

Fatal error: Uncaught Error: Class 'Spiral\Goridge\StreamRelay' not found in /var/www/test/roadrunner/psr-worker.php on line 5

Error: Class 'Spiral\Goridge\StreamRelay' not found in /var/www/test/roadrunner/psr-worker.php on line 5

Call Stack:
0.0001 400184 1. {main}() /var/www/test/roadrunner/psr-worker.php:0

DEBU[0000] [rpc]: stopped

What else I need to do for starting your "product"?
Could you please make convenient instructions for running the simplest example.
It is not user friendly now.

Config validation: Crash (segfault) when running in Docker

I suspect this is just due to the base image being incompatible with the release artifact - having an official Docker image with a correctly-built binary may solve the problem (and would be far more convenient to use either way). I was also unsuccessful at building the binary from source in a Docker image using the provided instructions - seemed to be an issue with dependencies, but I'm not very familiar with building Go projects.

FROM php:7.2.6-alpine
RUN wget -O /tmp/rr.tar.gz https://github.com/spiral/roadrunner/releases/download/v1.0.1/roadrunner-1.0.1-linux-amd64.tar.gz \
    && tar -xzvf /tmp/rr.tar.gz -C /tmp \
    && rm -rf /tmp/rr.tar.gz \
    && cp /tmp/roadrunner-1.0.1-linux-amd64/rr /usr/local/bin/rr \
    && rm -rf /tmp/roadrunner-1.0.1-linux-amd
WORKDIR www
# for debugging
ENTRYPOINT sh
/www # rr --config .rr.yaml -v serve
DEBU[0000] [http]: started
DEBU[0000] [static]: started
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x800a2a]

goroutine 7 [running]:
github.com/spiral/roadrunner.(*Server).Start(0xc42009c960, 0x0, 0x0)
	/Users/wolfy-j/go/src/github.com/spiral/roadrunner/server.go:70 +0xea
github.com/spiral/roadrunner/service/http.(*Service).Serve(0xc42006a480, 0x0, 0x0)
	/Users/wolfy-j/go/src/github.com/spiral/roadrunner/service/http/service.go:88 +0x211
github.com/spiral/roadrunner/service.(*container).Serve.func1(0xc42008fb60, 0xc42006aba0, 0xc4201fe7e0)
	/Users/wolfy-j/go/src/github.com/spiral/roadrunner/service/container.go:142 +0x8e
created by github.com/spiral/roadrunner/service.(*container).Serve
	/Users/wolfy-j/go/src/github.com/spiral/roadrunner/service/container.go:138 +0x1de

[๐Ÿ’กFEATURE REQUEST]: Streaming request [WIP] & responses [HTTP-DONE]

This project looks like it could be very useful in building a GRPC server bridge for PHP, which would be amazing.

GRPC has the concept of streaming request & responses, is that something you'd consider adding to roadrunner/goridge?

Thanks


This ticket (since most of the users know it) split into the four parts:

  • HTTP response streaming [done in v2023.3]
  • HTTP request streaming
  • gRPC response streaming
  • gRPC request streaming

Integration: Example with Slim app.

This started as a request for help in understanding the worker error: invalid prefix (checksum) error but I finally managed to figure that it was caused by not running slim silently.

Because that took me so long to realize I thought it might be helpful to show others an example.

<?php
ini_set('display_errors', 'stderr');
include "vendor/autoload.php";

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

$relay = new Spiral\Goridge\StreamRelay(STDIN, STDOUT);
$psr7 = new Spiral\RoadRunner\PSR7Client(new Spiral\RoadRunner\Worker($relay));

while ($req = $psr7->acceptRequest()) {
    try {

        // You must re-create the app on each request otherwise the response body doesn't reset in between calls.
        // It's likely there is a more efficient way around this but is outside the scope of the example.
        $app = new \Slim\App;

        // We set the request for slim to the one received by RoadRunners Worker.
        $container = $app->getContainer();
        $container['request'] = $req;

        // Now we're ready to declare any middle ware, routes, etc. etc.
        // You'd likely do this in other files and include them here.
        $app->post('/hello/{name}', function (Request $request, Response $response, array $args) {
            $parsedBody = $request->getParsedBody();
            $name = $args['name'];
            $response->getBody()->write("Hello, $name<br>" . json_encode($parsedBody));
            return $response;
        });

        // you MUST run the app silently!  We capture the Response object and pass hand it to the PSR7Client for responding to the server.
        $resp = $app->run(true);
        $psr7->respond($resp);
    } catch (\Throwable $e) {
        $psr7->getWorker()->error((string)$e);
    }
}

If this should be a pull request i'll make one. Again it started as asking about the invalid prefix error.

In addition: Would it be possible to make the invalid prefix error slightly less ambiguous? Searching for invalid prefix in the git doesn't lead to anything useful and changing it to worker error: invalid prefix (checksum) (make sure you aren't echoing before the worker responds to the server) or some other more verbose message about what is going on could help people new to the project.

Remove dependency on Zend Diactoros

Hi! I just discovered this wonderful package I'm super excited toying with it a lot.

There's just want problem. I'm trying it with some of my apps. Some of them use Zend Diactoros 2.0, which conflicts with the version the package uses.

I think this package shouldn't use any psr-7 implementation. Instead, we should use a psr-17 request factory.

So, what about creating a request using a, for example, RoadRunnerRequestFactory and drop diactoros? We don't care what the response object concrete implementation is anyway, so, why not?

Doing that we could even let other people implement their own request factories and use them in the worker.

The api I'm thinking is something along these lines:

$relay = new SocketRelay(SDTIN, STDOUT);
$worker = new Worker($relay);
$factory = new Psr7Factory($relay);
$client = new Psr7Client($factory);

Then, if someone wants to use diactoros, we could optionally provide an adapter for it, but never requiring the library, beacuse we typehinted the factory, that must return a psr-7 request.

Tell me what you think of it! :)

Server crash under Windows after a number of pool restarts

Windows 10 x64
RoadRunner 1.3
PHP 7.3.0
Pipes relay

I've set up File Watchers in PHPStorm to restart RR's pool on each source modification with the http:reset command. And after some time RR always crashes in this way:

INFO[5926] ::1 {145ms} 500 GET http://localhost:8090/v1/render
INFO[5926] ::1 {4.80ms} 500 GET http://localhost:8090/favicon.ico
INFO[5927] ::1 {3.08ms} 500 GET http://localhost:8090/v1/render
INFO[5927] ::1 {1.99ms} 500 GET http://localhost:8090/favicon.ico
INFO[5934] ::1 {3.90ms} 500 GET http://localhost:8090/v1/render
INFO[5934] ::1 {1.55ms} 500 GET http://localhost:8090/favicon.ico
INFO[5935] ::1 {6.91ms} 500 GET http://localhost:8090/v1/render
INFO[5935] ::1 {2.39ms} 500 GET http://localhost:8090/favicon.ico
DEBU[6397] new worker pool
DEBU[6397] new worker pool
panic: close of closed channel

goroutine 118 [running]:
github.com/spiral/roadrunner.(*StaticPool).Destroy(0xc0002c40b0)
        /mnt/c/Users/Wolfy-J/go/src/github.com/spiral/roadrunner/static_pool.go:155 +0x61
github.com/spiral/roadrunner.(*Server).Reconfigure.func1(0xc00013c9b0, 0xa51fa0, 0xc0002c40b0)
        /mnt/c/Users/Wolfy-J/go/src/github.com/spiral/roadrunner/server.go:145 +0x6c
created by github.com/spiral/roadrunner.(*Server).Reconfigure
        /mnt/c/Users/Wolfy-J/go/src/github.com/spiral/roadrunner/server.go:143 +0x2ec

Request: additional documentation for config file and RPC

Right now, there's little clear documentation about the RPC services that Roadrunner offers (nor what they offer) - really just how to enable it. From a comment in the reddit thread introducing this, being able to gather metrics are tangentially mentioned (prometheus was in an example) but it's unclear what can be exposed, how it can be extended, etc.

Related via #12 - guidelines for higher-level settings to run this successfully (e.g. php.ini, worker count, etc) would also be really helpful. Coming from php-fpm, it's hard to know what translates across or, more generally, what best practices are.

Symfony worker (for inclusion in the wiki)

Hi, thanks for this very interesting project!

Here is a worker to serve apps based on the default Symfony skeleton:

<?php
// worker.php
// Install the following mandatory packages:
// composer req spiral/roadrunner symfony/psr-http-message-bridge

ini_set('display_errors', 'stderr');

use App\Kernel;
use Spiral\Goridge\StreamRelay;
use Spiral\RoadRunner\PSR7Client;
use Spiral\RoadRunner\Worker;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Component\Debug\Debug;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;

require 'vendor/autoload.php';

// The check is to ensure we don't use .env in production
if (!isset($_SERVER['APP_ENV']) && !isset($_ENV['APP_ENV'])) {
    if (!class_exists(Dotenv::class)) {
        throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
    }
    (new Dotenv())->load(__DIR__.'/.env');
}

$env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? 'dev';
$debug = (bool) ($_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? ('prod' !== $env));

if ($debug) {
    umask(0000);

    Debug::enable();
}

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts(explode(',', $trustedHosts));
}

$kernel = new Kernel($env, $debug);
$relay = new StreamRelay(STDIN, STDOUT);
$psr7 = new PSR7Client(new Worker($relay));
$httpFoundationFactory = new HttpFoundationFactory();
$diactorosFactory = new DiactorosFactory();

while ($req = $psr7->acceptRequest()) {
    try {
        $request = $httpFoundationFactory->createRequest($req);
        $response = $kernel->handle($request);
        $psr7->respond($diactorosFactory->createResponse($response));
        $kernel->terminate($request, $response);
        $kernel->reboot(null);
    } catch (\Throwable $e) {
        $psr7->getWorker()->error((string)$e);
    }
}

And the corresponding .rr.yaml file:

http:
  address: 0.0.0.0:8080
  workers:
    command: "php test-sf/worker.php"
    pool:
      numWorkers: 4

static:
  dir:   "test-sf/public"
  forbid: [".php", ".htaccess"]

Would you mind including it in the wiki?

rpc unix socket is not closed sometimes

There is some issues with the shutdown procedures, when using either STDOUT/IN or Unix socket it doesn't close it, and then it can't start properly later (I havent tried a TCP socket yet).

./rr serve -v -d
DEBU[0000] [rpc]: started                               
DEBU[0000] [http]: started                              
DEBU[0000] [static]: started                            
ERRO[0000] [rpc]: listen unix ./var/roadrunner2.sock: bind: address already in use 
DEBU[0000] [http]: stopped                              
ERRO[0000] [http]: listen unix ./var/roadrunner2.sock: bind: address already in use 
^C%                                                                                   

Symfony: Default SESSION does not work (no cookie is set in Response)

Hi!

I have this code:

<?php
/**
 * Created by PhpStorm.
 * User: richard
 * Date: 22.06.18
 * Time: 11:59
 */

require __DIR__ . '/vendor/autoload.php';

use App\Kernel;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Component\Debug\Debug;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;

if (getenv('APP_ENV') === false) {
    (new Dotenv())->load(__DIR__.'/.env');
}
$env = getenv('APP_ENV') ?: 'dev';
$debug = getenv('APP_DEBUG') ? ((bool) getenv('APP_DEBUG')) : !in_array($env, ['prod', 'k8s']);

if ($debug) {
    umask(0000);
    Debug::enable();
}
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}
if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts(explode(',', $trustedHosts));
}
$kernel = new Kernel($env, $debug);
$httpFoundationFactory = new HttpFoundationFactory();




$relay = new Spiral\Goridge\StreamRelay(STDIN, STDOUT);
$psr7 = new Spiral\RoadRunner\PSR7Client(new Spiral\RoadRunner\Worker($relay));


while ($req = $psr7->acceptRequest()) {
    try {
        $request = $httpFoundationFactory->createRequest($req);
        $response = $kernel->handle($request);

        $psr7factory = new DiactorosFactory();
        $psr7response = $psr7factory->createResponse($response);
        $psr7->respond($psr7response);

        $kernel->terminate($request, $response);
    } catch (\Throwable $e) {
        $psr7->getWorker()->error((string)$e);
    }
}

It's slighly modified Symfony code to handle env-variables :)
(Also, it's stunningly fast!!!!)

But I don't get any cookies returned, so I can see my logg inn is accepted, and I'm redirected to the dashboard, but there I get a permission denied and redirect to login (because no cookies have been set)...

Any tips on how to troubleshoot, or what might be wrong?

PSR 7 Request is not compatible with HttpFoundationFactory

Problem

I found a issue with the request uri. The PSR7 Request is created with 2 request URI's, we have it in the header with "REQUEST_URI" and in the $ctx['uri'] which will be given as uri to Request object.

The REQUEST_URI header seems to be every time the first called URL of the worker and the $ctx['uri'] the right URI.

The problem now is the Symfony HttpFoundationFactory writes the PSR7 Request URI as REQUEST_URI (https://github.com/symfony/psr-http-message-bridge/blob/master/Factory/HttpFoundationFactory.php#L42)
but the wrong REQUEST_URI in the headers breaks it again to the first url. (https://github.com/symfony/psr-http-message-bridge/blob/master/Factory/HttpFoundationFactory.php#L48)

My Temporary Solution

After this line https://github.com/spiral/roadrunner/blob/master/src/PSR7Client.php#L76 to do

if (isset($_SERVER['REQUEST_URI'])) {
            unset($_SERVER['REQUEST_URI']);
}

This should be fixed in the Go part

Incorrect behavior of http:reset (error_log handler is lost)

Consider the following php code main.php:

<?php
/**
 * @var Goridge\RelayInterface $relay
 */
use Spiral\Goridge;
use Spiral\RoadRunner;

ini_set( 'display_errors', 'stderr' );

require_once( 'vendor/autoload.php' );

$worker = new RoadRunner\Worker( new Goridge\StreamRelay( STDIN, STDOUT ) );
$psr7 = new RoadRunner\PSR7Client( $worker );

while ( $req = $psr7->acceptRequest() ) {
    try {
        $resp = new \Zend\Diactoros\Response();

        $msg = 'msg 1';
        error_log( $msg );
        $resp->getBody()->write( $msg );

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

Note the lines:

ini_set( 'display_errors', 'stderr' );
        $msg = 'msg 1';
        error_log( $msg );
        $resp->getBody()->write( $msg );

rr.json

{
  "http": {
    "address": "0.0.0.0:8880",
    "workers": {
      "command": "/usr/bin/php /home/foo/src/boo/main.php",
      "pool": {
        "numWorkers": 4
      }
    }
  }
}

Start rr with the command: ~/bin/roadrunner/1.2.6/rr serve -d -v -c rr.json and send a http request to it. You'll see the msg 1 in console of your terminal and browser window.

Now change msg 1 to say msg 2 and reset rr with the following command ~/bin/roadrunner/1.2.6/rr http:reset -d -v -c rr.json Send a http request again, you'll see msg 2 in browser, but not in terminal window.

It looks like rr has a problem with stderr after reset.

[Feature Request] Watchers

Watchers - jobs generating special request from RR to workers.
This feature may useful for keep/close connection in workers, or many other custom jobs.

Suggestions:

  • Configure any counts of watchers
  • Worker must recieve information about watcher his called (to know whitch jobs to run)
  • 3 types of triggers
    • Triggered once after specific idle time
    • Triggered periodicaly by specific timer
    • Triggered periodicaly by specific timer only in idle state

SF Wiki entry outdated

Instead .rr there should be .rr.yaml

The error message was also nothing saying "WARN[0000] config: Config File ".rr" Not Found in ". There was a .rr file but he wanted a .rr.yaml ๐Ÿ˜‚

Distribute binary through composer

What about include build binary to composer install?
To update need to do two thing: update composer and update binary. This is not convenient.

Unsupported HTTP protocol version "2.0"

I recently upgraded from RoadRunner 1.2.4 to the currently latest version 1.2.6, including upgrading composer requirements to "spiral/roadrunner": "1.2.6"

Since 1.2.5 src/PSR7Client.php uses withProtocolVersion(substr($ctx['protocol'], 5)) (Line 87)

Unfortunately this results - if RoadRunner's https-Support is active - in a string 2.0 which won't validate against zend-diactoros (v.1.8.6) MessageTrait::validateProtocolVersion($version)

[...]
  // HTTP/1 uses a "<major>.<minor>" numbering scheme to indicate
        // versions of the protocol, while HTTP/2 does not.
        if (! preg_match('#^(1\.[01]|2)$#', $version)) {
            throw new InvalidArgumentException(sprintf(
                'Unsupported HTTP protocol version "%s" provided',
                $version
            ));
        }
[...]

which only accepts 1.0, 1.1 and 2.


Fatal error: Uncaught InvalidArgumentException: Unsupported HTTP protocol version "2.0" provided in /home/bof09595/PhpstormProjects/rr/vendor/zendframework/zend-diactoros/src/MessageTrait.php on line 371

InvalidArgumentException: Unsupported HTTP protocol version "2.0" provided in /home/bof09595/PhpstormProjects/rr/vendor/zendframework/zend-diactoros/src/MessageTrait.php on line 371

Call Stack:
    0.0002     395832   1. {main}() /home/bof09595/PhpstormProjects/rr/psr-worker.php:0
    0.0110     583008   2. Spiral\RoadRunner\PSR7Client->acceptRequest() /home/bof09595/PhpstormProjects/rr/psr-worker.php:18
    2.2204     759960   3. Zend\Diactoros\ServerRequest->withProtocolVersion() /home/bof09595/PhpstormProjects/rr/vendor/spiral/roadrunner/src/PSR7Client.php:87
    2.2204     759960   4. Zend\Diactoros\ServerRequest->validateProtocolVersion() /home/bof09595/PhpstormProjects/rr/vendor/zendframework/zend-diactoros/src/MessageTrait.php:84

This behavior renders https support useless for the moment.

Manipulate with config using rr args `rr serve --numWorkers=1`

One code can be run on different servers (dev,test,prod) with various core numbers. With this is a bad idea to hardcode workers number in config.
For example this how we run phpunit:

paratest --processes=$(grep -c ^processor /proc/cpuinfo || 4)

I think it's good to be option like rr serve --numWorkers=12

I also like Traefik approach where every parameters can manipulate through cli options.

services:
  traefik:
    image: traefik:1.5
    command:
      - "--api"
      - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
      - "--entrypoints=Name:https Address::443 TLS"
      - "--defaultentrypoints=http,https"
      - "--acme"
      - "--acme.storage=/etc/traefik/acme/acme.json"
      - "--acme.entryPoint=https"
      - "--acme.httpChallenge.entryPoint=http"
      - "--acme.onHostRule=true"
      - "--acme.onDemand=false"
      - "[email protected]"
      - "--docker"
      - "--docker.swarmMode"
      - "--docker.domain=mydomain.ca"
      - "--docker.watch"

Is this just for PHP?

This looks pretty neat, but can support for other languages be added or is this only ever going to be PHP?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.