Giter Site home page Giter Site logo

roadrunner-php / laravel-bridge Goto Github PK

View Code? Open in Web Editor NEW
373.0 373.0 25.0 225 KB

🌉 RoadRunner ⇆ Laravel bridge 🇺🇦❤️

Home Page: https://roadrunner.dev/docs/integration-laravel

License: MIT License

PHP 98.82% Dockerfile 0.44% Makefile 0.74%
laravel package roadrunner

laravel-bridge's People

Contributors

assurrussa avatar butschster avatar dependabot[bot] avatar tarampampam avatar

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

laravel-bridge's Issues

Laminas\Diactoros\Exception\InvalidArgumentException: Invalid header value type; must be a string or numeric;

Describe the bug

If you want to install laravel 8 in the configuration file cors.php change the value of supports_credentials to true we get the following error

Laminas\Diactoros\Exception\InvalidArgumentException: Invalid header value type; must be a string or numeric; received NULL in /var/www/vendor/laminas/laminas-diactoros/src/HeaderSecurity.php:140
Stack trace:
#0 /var/www/vendor/laminas/laminas-diactoros/src/MessageTrait.php(399): Laminas\Diactoros\HeaderSecurity::assertValid(NULL)
#1 [internal function]: Laminas\Diactoros\Response->Laminas\Diactoros\{closure}(NULL)
#2 /var/www/vendor/laminas/laminas-diactoros/src/MessageTrait.php(402): array_map(Object(Closure), Array)
#3 /var/www/vendor/laminas/laminas-diactoros/src/MessageTrait.php(213): Laminas\Diactoros\Response->filterHeaderValue(Array)
#4 /var/www/vendor/symfony/psr-http-message-bridge/Factory/PsrHttpFactory.php(163): Laminas\Diactoros\Response->withHeader('access-control-...', Array)
#5 /var/www/vendor/spiral/roadrunner-laravel/src/Worker.php(86): Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory->createResponse(Object(Illuminate\Http\Response))
#6 /var/www/vendor/spiral/roadrunner-laravel/bin/rr-worker(77): Spiral\RoadRunnerLaravel\Worker->start(false)
#7 {main}

it seems to me that the fruitcake/laravel-cors package supplied by default with laravel 8 should be removed since roadrunner solves this case, and it may be worth documenting this moment

System information

PHP version 8,0,1
Current package version 3.7
RoadRunner version 1.9.2
Environment docker

RoadRunner configuration file content

rpc:
  enable: false

http:
  address: 0.0.0.0:80
  ssl:
    port:     443
    redirect: false
  maxRequestSize: 200

  uploads:
    forbid: [ ".php", ".exe", ".bat" ]
    trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ]

  workers:
    command: "php ./vendor/bin/rr-worker  --refresh-app --reset-redis-connections"
    relay: "pipes"
    user: ""
    pool:
      numWorkers: 16
      maxJobs: 64
      allocateTimeout: 60
      destroyTimeout: 60

headers:
  cors:
    allowedOrigin: "*"
    allowedHeaders: "*"
    allowedMethods: "GET,POST,PUT,DELETE"
    allowCredentials: true
    exposedHeaders: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma"
    maxAge: 600
  response:
    "X-Powered-By": "RoadRunner"

static:
  dir: "public"
  forbid: [ ".php", ".htaccess" ]
  response:
    "X-Powered-By": "RoadRunner"

reload:
  interval: 1s
  patterns: [ ".php" ]

  services:
    http:
      dirs: [ "" ]
      recursive: true

config/roadrunner.php - standart

Additional context

# https://hub.docker.com/_/php/
FROM php:8.0-cli-alpine

ENV RR_VERSION 1.9.2

# Install dev dependencies
RUN apk add --no-cache --virtual .build-deps \
    $PHPIZE_DEPS \
    curl-dev \
    libtool \
    libxml2-dev \
    postgresql-dev \
    sqlite-dev \

# Install production dependencies
&& apk add --no-cache \
    bash \
    shadow \
    nano \
    curl \
    wget \
    freetype-dev \
    icu-dev \
    icu-libs \
    libc-dev \
    libjpeg-turbo-dev \
    libpng-dev \
    libzip-dev \
    make \
    oniguruma-dev \
    openssh-client \
    postgresql-libs \
    rsync \
    jpegoptim optipng pngquant gifsicle \
    zlib-dev \

# Install PECL and PEAR extensions
&& pecl install \
    redis \

# Enable PECL and PEAR extensions
&& docker-php-ext-enable \
    redis \

# Configure php extensions
&& docker-php-ext-configure gd --with-freetype --with-jpeg \

# Install php extensions
&& docker-php-ext-install \
    bcmath \
    calendar \
    curl \
    exif \
    gd \
    iconv \
    intl \
    mbstring \
    opcache \
    pdo \
    pdo_pgsql \
    pdo_sqlite \
    pcntl \
    sockets \
    tokenizer \
    xml \
    zip

# Copy php.ini configuration
COPY php.ini /usr/local/etc/php/conf.d/40-custom.ini
# Copy opcache.ini configuration
COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini

# Install composer
ENV COMPOSER_HOME /composer
ENV PATH ./vendor/bin:/composer/vendor/bin:$PATH
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN curl -s https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer

# Download RoadRunner
RUN mkdir /tmp/rr \
  && cd /tmp/rr \
  && echo "{\"require\":{\"spiral/roadrunner\":\"${RR_VERSION}\"}}" >> composer.json \
  && composer install \
  && vendor/bin/rr get-binary -l /usr/local/bin \
  && rm -rf /tmp/rr

# Cleanup dev dependencies
RUN apk del -f .build-deps && rm -rf /var/cache/apk/* && docker-php-source delete && rm -rf /tmp/pear

RUN usermod -u 1000 www-data && groupmod -g 1000 www-data

WORKDIR /var/www

USER 1000:1000

EXPOSE 80
EXPOSE 443

CMD ["/usr/local/bin/rr", "serve", "-c", "/var/www/.rr.yml", "-w", "/var/www", "-d"]
 

Использование воркеров под разные плагины RR

Насколько я понимаю сейчас RR может работать только с HTTP и если, допустим, мне необходимо добавить TCP плагин, то мне необходимо для него использовать альтернытивный воркер со своим обработчиком TCP запросов

rr-grpc & rr can't work together

When composer.json add the require below ,the packages can install ,but the command rr serve -d can't work
"spiral/php-grpc": "^1.0",
"spiral/roadrunner-laravel": "^3.0"

When composer.json add the require below ,the dependencies conflict
"spiral/php-grpc": "^1.0",
"spiral/roadrunner-laravel": "^4.0"

Hi, wonder if there is a plan to support laravel 9.0 ?

If you have any questions feel free to ask

laravel 9.0 released at 02/09. now I'm trying to upgrade got a problem.

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires laravel/framework ^9.0 -> satisfiable by laravel/framework[v9.0.0].
    - spiral/roadrunner-laravel v5.6.0 requires illuminate/view ~6.0 || ~7.0 || ~8.0 -> satisfiable by illuminate/view[v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.0].
    - Only one of these can be installed: illuminate/view[v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.0, v9.0.0], laravel/framework[v9.0.0]. laravel/framework replaces illuminate/view and thus cannot coexist with it.
    - Root composer.json requires spiral/roadrunner-laravel ^5.6 -> satisfiable by spiral/roadrunner-laravel[v5.6.0].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

seems like roadrunner-laravel is lock to 8.0 version.

Laravel Telescope shows its own http requests in the Requests list.

Is your feature request related to a problem?

Yes
image

Describe the solution you'd like

The solution from avto-dev/roadrunner-laravel#23 helped, but I would like it to work out of the box. Is it possible to examine the behavior of Laravel Octane relative to the Laravel Telescope?

Additional context

"laravel/telescope": "^4.5",
"laravel/framework": "^8.40",
"spiral/roadrunner-laravel": "^5.0"
php:8.0.7-cli
spiralscout/roadrunner:2.2.1

Register service provider?

Hello Laravel experts!

In our application, we use JWT authorization, and previously on laravel (not RR), we simpy use: https://github.com/tymondesigns/jwt-auth

But when we move to RR, we get some errors, like:

Auth driver [jwt] for guard [api] is not defined.

We fix this error moving \Tymon\JWTAuth\Providers\LaravelServiceProvider::class from app.php ( providers block ) to roadrunner.php ( reset_providers block), but, recently we noticed that this causes a memory leak. Even on Hello world responses, any ideas, how we can register it normally without memory leak?

Laravel Octane

Laravel has released first party package octane to support Roadrunner.

Do we need to migrate to octane on going forward?

Compatibility with Telescope

Describe the bug

Laravel Telescope's service provider accesses the current request in boot() to determine if this request should be recorded. Trace below:

At this point the request object is not bound. The request will default resolve to a root path (/). And since the provider is not reset on each request by default, this means every request will be logged, ignoring the Telescope request filters. This is the cause of the issue reported here: avto-dev/roadrunner-laravel#23

Configuring TelescopeServiceProvider to reset via the reset_providers config does not fix this issue. By default, providers are reset during BeforeLoopIterationEvent, and the BindRequestListener is run afterward, during the BeforeRequestHandlingEvent. This means that even though the provider will get reset, since the request is resolved during the boot() call, the path seems to always resolve to /.

I attempted to create my own ResetTelescopeListener and fire it after the BindRequestListener is called:

class ResetTelescopeListener implements ListenerInterface
{
    public function handle($event): void
    {
        if ($event instanceof WithApplication) {
            $app = $event->application();

            $provider = new \Laravel\Telescope\TelescopeServiceProvider($app);
            $provider->register();
            $app->call([$provider, 'boot']);
        }
    }
}

However, this still doesn't seem to fix the issue. It's not clear to me why. It seems like the provider is getting initialized twice on every request.

I'm not sure if there is a path forward without requesting a change on their end.

Expected behaviour

There is a clearly defined path for using Laravel Telescope with roadrunner and roadrunner-laravel.

Actual behaviour

It is unclear how to use Laravel Telescope with roadrunner and roadrunner-laravel.

Steps to reproduce

  1. Install Laravel Telescope, roadrunner, and roadrunner-laravel
  2. In the Laravel Telescope requests dashboard, observe that all requests to /telescope are being logged, ignoring the default filters defined here.

System information

Key Value
PHP version 8.0
Current package version 3.7.0
RoadRunner version 1.8.3
Environment Docker

RoadRunner configuration file content

http:
  address: 0.0.0.0:80
  workers:
    command: 'php ./vendor/bin/rr-worker'

static:
  dir: 'public'

reload:
  enabled: false

Package configuration file content

Defaults with changes to debug described above.

Additional context

N/A

How to deploy on AWS?

If you have any questions feel free to ask

Hi, I feel dumb for asking this but I'm not sure where else to ask it. I managed to successfully deploy my laravel application with roadrunner, but now I want to go into production. Up until now I've been using the following command to start the server:

./rr -c ./.rr.yaml serve -d

I've tried the same command via putty to my EC2 instance and it's working. However, when I close my putty connection, the server also shuts down.

Is there a way to enable Roadrunner and keep it running?

Can't start application

Hello.
Set up fresh laravel installation.
Made .rr.yaml file with example config provided here and trying to start rr with ./rr.exe -c ./.rr.yaml serve -d on windows or ./rr -c ./.rr.yaml serve -d on WSL2 but both gives me an error ERRO[0000] [http]: [http]: unable to connect to worker: invalid data found in the buffer (possible echo): exit status 1 Error: [http]: unable to connect to worker: invalid data found in the buffer (possible echo): exit status 1

Disk problem on uploading files.

First, Thanks for the great package!

I found that lots of temporary files remained in the tmp directory after file uploading.
Temporary files will be removed for every request if using nginx + fpm.
Is something not working or do I need to hook an event to remove it?

Roadrunner not working on stancl/tenancy

Describe the bug

I've try to run my project via Roadrunner and the apps run smoothly for login and authenticate login from central db, but when i try to connect to tenant, i got an exception Database connection [tenant] not configured. while try to impersonate the session and there's no problem while running via php artisan serve

image

Expected behaviour

The expected behaviour Roadrunner should be identified multiple tenant connection

Actual behaviour

The actual behaviour tenant couldn't be identified while running via Roadrunner

Steps to reproduce

Describe steps to behavior reproducing.

System information

Please, complete the following information:

Key Value
PHP version PHP 7.4.16
Current package version 4.0.0
RoadRunner version 2.0.2
Environment local
Laravel Version 8.34.0
stancl/tenancy 3.4

RoadRunner configuration file content

rpc:
  enable: true
  listen: tcp://127.0.0.1:6001

# gRPC params
grpc:
  listen: "tcp://127.0.0.1:9090" # gRPC is enabled on port 9090
  proto: "test.proto"
  workers:
    command: "php worker.php"
    pool:
      numWorkers: 1 # Since we have a cache that's based on an instance variable, we can only have 1 worker for this sample scenario

server:
  command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///tmp/rr-rpc.sock"
  relay: "unix:///tmp/rr-rpc.sock"

http:
  address: 0.0.0.0:8080
  middleware: ["headers", "static", "gzip"]
  pool:
    max_jobs: 64 # feel free to change this
    supervisor:
      exec_ttl: 60s
  headers:
    response:
      X-Powered-By: "RoadRunner"
  static:
    dir: "public"
    forbid: [".php"]

# monitors rr server(s)
limit:
  # check worker state each second
  interval: 1

  # custom watch configuration for each service
  services:
    # monitor http workers
    grpc:
      # maximum allowed memory consumption per worker (soft)
      maxMemory: 100

      # maximum time to live for the worker (soft)
      TTL: 0

      # maximum allowed amount of time worker can spend in idle before being removed (for weak db connections, soft)
      idleTTL: 0

      # max_execution_time (brutal)
      execTTL: 60

Package configuration file content

<?php

use Spiral\RoadRunnerLaravel\Events;
use Spiral\RoadRunnerLaravel\Listeners;

return [
    /*
    |--------------------------------------------------------------------------
    | Force HTTPS Schema Usage
    |--------------------------------------------------------------------------
    |
    | Set this value to `true` if your application uses HTTPS (required for
    | example for correct links generation).
    |
    */

    'force_https' => (bool) env('APP_FORCE_HTTPS', false),

    /*
    |--------------------------------------------------------------------------
    | Containers Pre Resolving
    |--------------------------------------------------------------------------
    |
    | Declared here abstractions will be resolved before events loop will be
    | started.
    |
    */

    'pre_resolving' => [
        'view',
        'files',
        'session',
        'session.store',
        'routes',
        'db',
        'db.factory',
        'cache',
        'cache.store',
        'config',
        'cookie',
        'encrypter',
        'hash',
        'router',
        'translator',
        'url',
        'log',
    ],

    /*
    |--------------------------------------------------------------------------
    | Event Listeners
    |--------------------------------------------------------------------------
    |
    | Worker provided by this package allows to interacts with request
    | processing loop using application events. Feel free to add your own event
    | listeners.
    |
    */

    'listeners' => [
        Events\BeforeLoopStartedEvent::class => [
            Listeners\FixSymfonyFileValidationListener::class,
        ],

        Events\BeforeLoopIterationEvent::class => [
            Listeners\EnableHttpMethodParameterOverrideListener::class,
            Listeners\RebindHttpKernelListener::class, // Laravel 7 issue: <https://git.io/JvPpf>
            Listeners\RebindViewListener::class,
            Listeners\CloneConfigListener::class,
            Listeners\UnqueueCookiesListener::class,
            Listeners\ResetSessionListener::class,
            Listeners\ResetProvidersListener::class,
        ],

        Events\BeforeRequestHandlingEvent::class => [
            Listeners\RebindRouterListener::class,
            Listeners\InjectStatsIntoRequestListener::class,
            Listeners\BindRequestListener::class,
            Listeners\ForceHttpsListener::class,
            Listeners\SetServerPortListener::class,
        ],

        Events\AfterRequestHandlingEvent::class => [
            //
        ],

        Events\AfterLoopIterationEvent::class => [
            Listeners\ClearInstancesListener::class,
            Listeners\RunGarbageCollectorListener::class,
        ],

        Events\AfterLoopStoppedEvent::class => [
            //
        ],

        Events\LoopErrorOccurredEvent::class => [
            Listeners\SendExceptionToStderrListener::class,
            Listeners\StopWorkerListener::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Instances Clearing
    |--------------------------------------------------------------------------
    |
    | Instances described here will be cleared on every request (if
    | `ClearInstancesListener` is enabled).
    |
    */

    'clear_instances' => [
        'auth',
    ],

    /*
    |--------------------------------------------------------------------------
    | Reset Providers
    |--------------------------------------------------------------------------
    |
    | Providers that will be registered on every request (if
    | `ResetProvidersListener` is enabled).
    |
    */

    'reset_providers' => [
        Illuminate\Auth\AuthServiceProvider::class,
        // App\Your\Custom\AuthServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
    ],
];

Improve bridge performance and reduce memory consumption

At the moment most of the extensions work using symfony/psr-http-message-bridge which converts PSR-7 request/response into Symfony/HttpKernel.

The RoadRunner worker exposes low level API to access the incoming request data in the form of an array.

https://github.com/spiral/roadrunner-http/blob/master/src/HttpWorker.php

Essentially, it makes it possible to skip the PSR-7 implementation as whole and map data directly to Symfony Request/Response.

Benefits:

  • lower memory consumption (you can reuse Symfony requests)
  • higher performance
  • less dependencies

Issues with laravel url helper and port?

Hi guys

Just asking in case you happen to know about this. When configuring my application, I'm trying to make it work on port 8180, but for some reason the url helper is not recognizing the port, so for instance if I use route("tasks") the url I get is example.com/tasks instead of example.com:8180/tasks

This doesn't happen when I try php artisan serve, the url shows correctly the 8000 port. It works fine on apache as well. Wondering if maybe there is some settings I'm missing.

My rr.yaml file is as following:

env:
        APP_REFRESH: true

http:
        address: 0.0.0.0:8180
        workers:
                command: 'php ./vendor/bin/rr-worker'

static:
        dir: 'public/'

And I've also set the url with port in app_url in the .env file.

It works if I enter the url directly, it's just the helper that is not recognizing the port for some reason.

Add support anothe connection methods

Hi

Is your feature request related to a problem?

At the moment, there is an urgent need to transport all application logs to the \STDOUT. As we can see from the RR config for communication, I can use:

  # connection method (pipes, tcp://:9000, unix://socket.unix). default "pipes"
  relay: "pipes"

I want to change the way to socket

  # connection method (pipes, tcp://:9000, unix://socket.unix). default "pipes"
  relay: "unix://socket.unix"

But I see an error in the console

Error: [http]: unable to connect to worker: worker is gone

Describe the solution you'd like

Add the settings for communication to the config config/roadrunner.php, thereby duplicating the lines from the .rr.yml file:

.rr.yml file

  # http worker pool configuration.
  workers:
    # php worker command.
    command: "php php-worker.php"

    # connection method (pipes, tcp://:9000, unix://socket.unix). default "pipes"
    relay: "unix://socket.unix"

config/roadrunner.php

/*
|--------------------------------------------------------------------------
| Connection method
|--------------------------------------------------------------------------
|
| Maybe:
|   For socket:
|       [
|            'type'    => 'socket',
|            'address' => 'rr.sock',
|            'port'    => null,
|        ]
|   For tcp:
|       [
|            'type'    => 'tcp',
|            'address' => 'localhost',
|            'port'    => 9000,
|        ]
|   For pipes (or dont touch):
|       [
|            'type'    => 'pipes',
|            'address' => null,
|            'port'    => null,
|        ]
|
*/

'relay' => [
    'type'    => 'socket',
    'address' => 'rr.sock',
    'port'    => null,
],

Add method in Spiral\RoadRunnerLaravel\Worker.php to check from config.

/**
 * @param string   $address
 * @param bool     $is_unix_sock
 * @param int|null $port
 *
 * @return RelayInterface
 */
protected function createSocketRelay(string $address, bool $is_unix_sock = false, ?int $port = null): RelayInterface
{
    return new \Spiral\Goridge\SocketRelay(
        $address,
        $port,
        $is_unix_sock
            ? \Spiral\Goridge\SocketRelay::SOCK_UNIX
            : \Spiral\Goridge\SocketRelay::SOCK_TCP
    );
}

Additional context

Only a pull request can close this issue.

roadrunner-laravel: 3.7.0
Laravel: 7
PHP: 7.3
RR: 1.9.2

Service Container -> Binding A Singleton

A clean installation of this repository, but:

.rr.local.yml

  # Workers pool settings.
  pool:
    # How many worker processes will be started. Zero (or nothing) means the number of logical CPUs.
    #
    # Default: 0
    num_workers: 2

MyCounter.php

<?php

namespace App\Singleton;


use Illuminate\Support\Facades\Log;

class MyCounter
{

    protected int $counter=0;

    public function __construct()
    {
        Log::debug('MyCounter __construct');

    }

    public function __destruct ()
    {
        Log::debug('MyCounter __destruct');
    }

    public function increment(): int
    {
         Log::debug('++');
         return ++$this->counter;
    }

}

In AppServiceProvider

    public function register()
    {
        $this->app->singleton('mc', function () {
            return new MyCounter();
        });
    }

In welcome.blade.php

   {{ app()->make('mc')->increment() }}

In the log file each request:

[2022-02-21 06:10:56] local.DEBUG: MyCounter __construct
[2022-02-21 06:10:56] local.DEBUG: ++
[2022-02-21 06:10:56] local.DEBUG: MyCounter __destruct

Obviously, the counter is reset every time.
Why? What am I doing wrong?

What power kills my singleton "mc"?

How to fix unable to connect to default worker?

I installed the composer package and followed instructions. But after running

$ rr -c ./.rr.yaml serve -d

I get the following error:

Error: [http]: unable to connect to worker: invalid data found in the buffer (possible echo): exit status 1

Is it something wrong with the ./vendor/bin/rr-worker file? I'm on windows.

To support php 8.2

I have a problem using it in php 8.2.

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /var/www/vendor/spiral/roadrunner-laravel/src/Console/Commands/WorkerFactory.php on line 59
Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /var/www/vendor/spiral/roadrunner-laravel/src/Console/Commands/WorkerFactory.php on line 63

https://github.com/spiral/roadrunner-laravel/blob/master/src/Console/Commands/WorkerFactory.php#L59
https://github.com/spiral/roadrunner-laravel/blob/master/src/Console/Commands/WorkerFactory.php#L63

https://php.watch/versions/8.2/$%7Bvar%7D-string-interpolation-deprecated

I have that problem.

Any chance of supporting PHP 8.2?

Support PHP8?

Will there be support for php 8 in the near future?

Pcov || XDebug with RR

Hello!

Is your feature request related to a problem?

It is noted in the Dockerfile that xdebug is supposed to be used. But there are no settings for the RoadRunner.

Describe the solution you'd like

  • If xdebug is only used to cover code with tests, it may be possible to use pcov instead?
  • Or maybe add documentation with examples on using the RoadRunner with xdebug?

Additional context

RR with debug: https://roadrunner.dev/docs/php-debugging
Pcov is built for PHPUnit code coverage not something else.

Add support for Lumen

Hi, I installed this package in a Lumen project and followed the readme.md steps, but I had some trouble starting the worker.

Are there any extra undocumented steps to make this work?

Thanks

listen unix /var/run/rr-rpc.sock: bind: permission denied

If you have any questions feel free to ask

I've tried to use roadrunner-laravel and follow the example instruction to run the worker and create relay in /var/run/rr-rpc.sock but i got permission denied because /var/run are owned by root

after that i tried to run as super user but all the generated session file is owned by root and cause some of the function not worked properly like database connection, etc

is there any solution for this issue?

laravel pagination always returning the first page (laravel as api backend)

Describe the bug

A clear and concise description of what the bug is.

Expected behaviour

Tell us what should happen.

Actual behaviour

Tell us what happens instead.

Steps to reproduce

Describe steps to behavior reproducing.

System information

Please, complete the following information:

Key Value
PHP version
Current package version
RoadRunner version
Environment

RoadRunner configuration file content

# Paste here your `.rr.yaml` file content

Package configuration file content

# Paste here your `config/roadrunner.php` file content

Additional context

Add any other context about the problem here.

move_uploaded_file() not working

Describe the bug

I tried this code:

    $file = request()->file('user');
    $file->move($targetDir, $newfilename);

will be get error:

Could not move the file \"Z:\\USERTEMP\\sym4B1D.tmp\" to \"E:\\UploadTest\\test\\200911000005\\200911000005-1.jpg\" ()

and I know this error comes from:

vendor/symfony/http-foundation/File/UploadedFile.php:
184            set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
185            $moved = move_uploaded_file($this->getPathname(), $target);
186            restore_error_handler();
187            if (!$moved) {
188                throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error)));
189            }

My temporary solution:

    $file = request()->file('user');
    $targetPathName = $targetDir . DIRECTORY_SEPARATOR . $newfilename;
    try {
        $file->move($targetDir, $newfilename);
    } catch (\Exception $err) {
        try {
            rename($file->getPathname(), $targetPathName);
        } catch (\Exception $err2) {
            throw new \Symfony\Component\HttpFoundation\File\Exception\FileException($err->getMessage());
        }
    }

Expectation

Simply using $file->move().
Thank you.

System information

Key Value
PHP version 8.0.6
Current package version 4.0
RoadRunner version 2
Environment local on Windows platform

RoadRunner configuration file content

server:
  command: "php ./vendor/spiral/roadrunner-laravel/bin/rr-worker start"

http:
  address: 0.0.0.0:8080
  middleware: ["headers", "static", "gzip"]
  pool:
    max_jobs: 64 # feel free to change this
    supervisor:
      exec_ttl: 60s
  headers:
    response:
      X-Powered-By: "RoadRunner"
    cors:
      allowed_origin: "*"
      allowed_headers: "*"
      allowed_methods: "*"
      allow_credentials: true
      exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,Server-Timing"
      max_age: 82600
  static:
    dir: "public"
    forbid: [".php"]
  http2:
    h2c: false
    max_concurrent_streams: 128
  uploads:
#    dir: "z:\temp"
    forbid: [".php", ".exe", ".bat", ".sh"]

logs:
#  mode: production
#  level: error

reload:
  # sync interval
  interval: 1s
  # global patterns to sync
  patterns: [ ".php", ".env" ]
  # list of included for sync services
  services:
    http:
      # recursive search for file patterns to add
      recursive: true
      # ignored folders
      ignore: [ "vendor" ]
      # service specific file pattens to sync
      patterns: [ ".php", ".env", ".go", ".md" ]
      # directories to sync. If recursive is set to true,
      # recursive sync will be applied only to the directories in `dirs` section
      dirs: [ "." ]

Package configuration file content

<?php

use Spiral\RoadRunnerLaravel\Events;
use Spiral\RoadRunnerLaravel\Listeners;

return [
    /*
    |--------------------------------------------------------------------------
    | Force HTTPS Schema Usage
    |--------------------------------------------------------------------------
    |
    | Set this value to `true` if your application uses HTTPS (required for
    | example for correct links generation).
    |
    */

    'force_https' => (bool) env('APP_FORCE_HTTPS', false),

    /*
    |--------------------------------------------------------------------------
    | Containers Pre Resolving
    |--------------------------------------------------------------------------
    |
    | Declared here abstractions will be resolved before events loop will be
    | started.
    |
    */

    'pre_resolving' => [
        'auth',
        'cache',
        'cache.store',
        'config',
        'cookie',
        'db',
        'db.factory',
        'encrypter',
        'files',
        'hash',
        'log',
        'router',
        'routes',
        'session',
        'session.store',
        'translator',
        'url',
        'view',
    ],

    /*
    |--------------------------------------------------------------------------
    | Event Listeners
    |--------------------------------------------------------------------------
    |
    | Worker provided by this package allows to interacts with request
    | processing loop using application events. Feel free to add your own event
    | listeners.
    |
    */

    'listeners' => [
        Events\BeforeLoopStartedEvent::class => [
            Listeners\FixSymfonyFileValidationListener::class,
        ],

        Events\BeforeLoopIterationEvent::class => [
            Listeners\EnableHttpMethodParameterOverrideListener::class,
            Listeners\RebindHttpKernelListener::class, // Laravel 7 issue: <https://git.io/JvPpf>
            Listeners\RebindViewListener::class,
            Listeners\RebindAuthorizationGateListener::class,
            Listeners\RebindBroadcastManagerListener::class,
            Listeners\RebindDatabaseManagerListener::class,
            Listeners\RebindMailManagerListener::class,
            Listeners\RebindNotificationChannelManagerListener::class,
            Listeners\RebindPipelineHubListener::class,
            Listeners\RebindQueueManagerListener::class,
            Listeners\RebindValidationFactoryListener::class,
            Listeners\CloneConfigListener::class,
            Listeners\UnqueueCookiesListener::class,
            Listeners\FlushAuthenticationStateListener::class,
            Listeners\ResetSessionListener::class,
            Listeners\ResetProvidersListener::class,
            Listeners\ResetLocaleStateListener::class,

            // Listeners\ResetLaravelScoutListener::class, // for 'laravel/scout' package
            // Listeners\ResetLaravelSocialiteListener::class, // for 'laravel/socialite' package
            // Listeners\ResetInertiaListener::class, // for 'inertiajs/inertia-laravel' package
        ],

        Events\BeforeRequestHandlingEvent::class => [
            Listeners\RebindRouterListener::class,
            Listeners\InjectStatsIntoRequestListener::class,
            Listeners\BindRequestListener::class,
            Listeners\ForceHttpsListener::class,
            Listeners\SetServerPortListener::class,
        ],

        Events\AfterRequestHandlingEvent::class => [
            //
        ],

        Events\AfterLoopIterationEvent::class => [
            Listeners\FlushArrayCacheListener::class,
            Listeners\ResetDatabaseRecordModificationStateListener::class,
            Listeners\ClearInstancesListener::class,
            Listeners\RunGarbageCollectorListener::class,
        ],

        Events\AfterLoopStoppedEvent::class => [
            //
        ],

        Events\LoopErrorOccurredEvent::class => [
            Listeners\SendExceptionToStderrListener::class,
            Listeners\StopWorkerListener::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Instances Clearing
    |--------------------------------------------------------------------------
    |
    | Instances described here will be cleared on every request (if
    | `ClearInstancesListener` is enabled).
    |
    */

    'clear_instances' => [
        'auth', // is not required for Laravel >= v8.35
    ],

    /*
    |--------------------------------------------------------------------------
    | Reset Providers
    |--------------------------------------------------------------------------
    |
    | Providers that will be registered on every request (if
    | `ResetProvidersListener` is enabled).
    |
    */

    'reset_providers' => [
        Illuminate\Auth\AuthServiceProvider::class, // is not required for Laravel >= v8.35
        // App\Your\Custom\AuthServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class, // is not required for Laravel >= v8.35
	    App\Libs\Passport\PassportServiceProvider::class,
	    App\Libs\ServerTiming\ServerTimingServiceProvider::class,

    ],
];

Additional context

Add any other context about the problem here.

State resetting for the tighten/ziggy package

Сейчас при после пары обновлений страницы при использовании Jetstream с InertiaJs появляется ошибка.

Uncaught ReferenceError: Ziggy is not defined
Uncaught (in promise) ReferenceError: route is not defined

Причина ошибки связана с пакетом tightenco/ziggy в классе Tightenco\Ziggy\BladeRouteGenerator.

Сброс состояния в BladeRouteGenerator::$generated = false решает проблему.

Suggestion to Replace the command on publish config

From the published config of .rr.yaml.dist

workers:
    command:  "php psr-worker.php pipes"

I suggests to replace the command to be php ./vendor/bin/rr-worker pipes

This will avoid confusion with new people who'd like to try it out.

rr: Saving execution to trace directory

Describe the bug

When i run rr serve command it gives me this error message "execve failed: 'serve' (or interpreter) not found (ENOENT)"

my rr.yaml file content given below:

http:
  address: 127.0.0.1:8001
  ssl:
    # host and port separated by semicolon (default :443)
    address: :8000
    redirect: false
    cert: /home/tejal-gandhi/Desktop/ssl/apache.crt
    key: /home/tejal-gandhi/Desktop/ssl/apache.key

    h2c: false
    max_concurrent_streams: 128
  pool:
    num_workers: 0
    max_jobs: 500
    supervisor:
      exec_ttl: 30s
  static:
    dir: public
  middleware: ["static"]
  workers:
    pool:
      numWorkers: 1
      maxJobs:    1

server:
  command: "php ./vendor/bin/roadrunner-worker"

  env:
    - APP_ENV: production
    - APP_BASE_PATH: "/home/tejal-gandhi/Desktop/octane"
    - LARAVEL_OCTANE: "1"

rpc:
  listen: tcp://127.0.0.1:6001

logs:
  mode: production
  level: debug
  output: stdout
  encoding: json

Memory leak

Describe the bug

If you request a page that does not exist (error 404), there is a memory leak.

And after several such requests Worker is closed because the memory consumption limit is exceeded.

Steps to reproduce the behavior:

It is easy to reproduce. Create a new clean Laravel 7 project, launch it under RR (with unlimited number of requests for Worker) and make a hundred calls to a page that does not exist and watch the log.

Feature request: Add beforeApplicationStartedEvent

Greetings!

First of all, thanks for the awesome package!

I am using laravel-roadrunner in production and experimenting with Event Loop System.

I need to declare a couple of application metrics(counters) and load default values before application starts (default counter values saved in local redis storage and must be synced with app metrics after docker container with main app restarts).

The metrics I am doing in following way: https://roadrunner.dev/docs/beep-beep-metrics

As far as I understand, the package provides BeforeLoopStarted and BeforeLoopIteration events
and theoretically I can place the code of metrics syncing to the BeforeLoopStart event listener.

But, if we have more than one rr worker, event will be listened many times.

So, my idea is to define something like beforeApplicationStartedEvent which will be listened only once.

Can you provide such an event in the future or help to understand how to implement it?

Thanks.

Performance degradation with sessions. Laravel 8. Docker

Hello.
I have a docker container with RoadrRunner and Laravel 8.16.1 by default. (clean install laravel new www)

I try it many times:
ab -n 1000 -c 100 "http://serverhost:8080/"

I notice a degradation of app performance:

3113.96 [#/sec]
....
1024.88 [#/sec]
539.06 [#/sec]
439.41 [#/sec]

If i remove in Http/Kernel.php in $middlewareGroups
these lines:

\Illuminate\Session\Middleware\StartSession::class, 
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class, 

then performance not degrade:

Requests per second:    2844.97 [#/sec] (mean)
Time per request:       35.150 [ms] (mean)
Time per request:       0.351 [ms] (mean, across all concurrent requests)

I suppose I need to reset the sessions? Only with the default config, roadrunner-laravel does not work.
How can I do it?

Dockerfile

FROM php:7.4-cli

#COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini

RUN apt-get update && apt-get install -y \
        curl \
  		vim \
  		libfreetype6-dev \
  		libjpeg62-turbo-dev \
  		libmcrypt-dev \
  		libpng-dev \
  		zlib1g-dev \
  		libxml2-dev \
  		libzip-dev \
  		libonig-dev \
  		graphviz \
  		libcurl4-openssl-dev \
  		pkg-config \
  		libpq-dev \
  		iputils-ping \
  		wget \
  		git

# Install PHP Extensions
RUN docker-php-ext-install -j$(nproc) iconv mbstring mysqli pdo_mysql zip \
    && docker-php-ext-install opcache \
    && docker-php-ext-enable opcache

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Download RoadRunner
ENV RR_VERSION 1.8.4
RUN mkdir /tmp/rr \
  && cd /tmp/rr \
  && echo "{\"require\":{\"spiral/roadrunner\":\"${RR_VERSION}\"}}" >> composer.json \
  && composer install --ignore-platform-reqs \
  && vendor/bin/rr get-binary -l /usr/local/bin \
  && rm -rf /tmp/rr

## Copy RoadRunner config
COPY config /etc/roadrunner

WORKDIR /var/www

CMD ["/usr/local/bin/rr", "serve", "-c", "/etc/roadrunner/.rr.yaml", "-w", "/var/www"]

docker-compose.yml

version: "3.7"
services:
  roadrunner:
    build: ./images/roadrunner
    container_name: "roadrunner"
    ports:
      - 8080:8080
    volumes:
      - ./www:/var/www:cached
      - ./configs/roadrunner:/etc/roadrunner:cached
    network_mode: "host"

.rr.yaml

env:
#APP_REFRESH: true

http:
  address: 0.0.0.0:8080
  workers:
    command: 'php /var/www/vendor/bin/rr-worker' # for windows: `php vendor/spiral/roadrunner-laravel/bin/rr-worker`
static:
  dir: 'public'

reload:
 interval: 1s
 patterns: [".php"]
 services:
   http:
     dirs: [""]
     recursive: true

How to configure Auth0?

If you have any questions feel free to ask

Hi, me again. I'm currently running an application on Laravel and have sucessfully configured roadrunner-laravel, however my application is using Auth0 authentication.

Is there an easy way to configure auth0? Or at least some documentation or pointers on what should I configure in order for it to work?

The error I'm getting is:

InvalidArgumentException
Authentication user provider [auth0] is not defined. 

ParseError Causes Unresponsive Worker

Describe the bug

When the code contains a syntax error the RR worker locks up and never responds.

Expected behaviour

An Ignition debug page

Actual behaviour

RR worker goes to 100% CPU and the browser times out

Steps to reproduce

  1. Install completely vanilla Laravel
  2. Install RR integration
  3. Write code with syntax error. Eg:

routes/web.php

<?php

use Illuminate\Support\Facades\Route;


Route::get('/', function () {
    return view('welcome');
});

syntaxerror

System information

Key Value
PHP version 8.2.9
Current package version v5.12.0
RoadRunner version 2023.2.0
Environment docker
Laravel version 10.20.0

RoadRunner configuration file content

version: "3"

http:
  address: 0.0.0.0:8000
  pool:
    debug: true

server:
  command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr-relay.sock"
  relay: "unix:///var/run/rr-relay.sock"

rpc:
  listen: tcp://127.0.0.1:6001

Package configuration file content

Using the default

https://github.com/roadrunner-php/laravel-bridge/blob/v5.12.0/config/roadrunner.php

Additional context

If I add logging to the .rr.yaml:

logs:
  mode: production
  level: debug
  output: stdout
  encoding: json

I can see the following, and it just keeps repeating:

(lines truncated for brevity)

{"level":"debug","ts":1693066706217844325,"logger":"rpc","msg":"plugin was started","address":"tcp://127.0.0.1:6001","list of the plugins with RPC methods:":["lock","informer","app","resetter"]}
{"level":"debug","ts":1693066706218196887,"logger":"http","msg":"http server was started","address":"0.0.0.0:8000"}
[INFO] RoadRunner server started; version: 2023.2.2, buildtime: 2023-08-10T16:38:53+0000
{"level":"debug","ts":1693066724545294964,"logger":"server","msg":"worker is allocated","pid":15,"internal_event_name":"EventWorkerConstruct"}
{"level":"debug","ts":1693066724592002773,"logger":"server","msg":"sending stop request to the worker","pid":15}
{"level":"info","ts":1693066724608827321,"logger":"http","msg":"http log","status":200,"method":"GET","URI":"/","remote_address":"172.17.0.1:59198","read_bytes":0,"write_bytes":27514,"start":169306672
{"level":"debug","ts":1693066725075147149,"logger":"server","msg":"worker is allocated","pid":18,"internal_event_name":"EventWorkerConstruct"}
{"level":"debug","ts":1693066725111879408,"logger":"server","msg":"sending stop request to the worker","pid":18}
{"level":"debug","ts":1693066725132054119,"logger":"server","msg":"stderr","error":"read |0: file already closed"}
{"level":"info","ts":1693066725132635926,"logger":"http","msg":"http log","status":404,"method":"GET","URI":"/favicon.ico","remote_address":"172.17.0.1:59198","read_bytes":0,"write_bytes":6603,"start"
{"level":"info","ts":1693066736498534539,"logger":"server","msg":"<!DOCTYPE html>\n<html lang=\"en\" class=\"auto\">\n<!--\nParseError: syntax error, unexpected end of file in file /var/www/vhosts/tmp
{"level":"info","ts":1693066736499277807,"logger":"server","msg":".\",\"42\":\"     *\",\"43\":\"     * @param  \\\\Illuminate\\\\Container\\\\Container  $container\",\"44\":\"     * @param  string  $
{"level":"info","ts":1693066736499838389,"logger":"server","msg":"/\\/ for any listeners that need to do work after this initial booting gets\",\"987\":\"        \\/\\/ finished. This is useful when o
{"level":"info","ts":1693066736500500296,"logger":"server","msg":"}}var U=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Pro
{"level":"info","ts":1693066736501057659,"logger":"server","msg":"To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled 
{"level":"info","ts":1693066736501616268,"logger":"server","msg":"with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.\",We(t))),\"function\"==typeof r.getDerivedStateFrom
{"level":"info","ts":1693066736502188894,"logger":"server","msg":"ate;if(0!=(t.flags&ar))return t.lanes=n,0!=(8&t.mode)&&xd(t),t;var k=null!==x,A=!1;return null===e?void 0!==t.memoizedProps.fallback&&
{"level":"info","ts":1693066736502850481,"logger":"server","msg":",(e.documentElement.firstElementChild||e.documentElement.children[0]).appendChild(t),t=e.createElement(\"style\"),(e.documentElement.f
{"level":"info","ts":1693066736509620006,"logger":"server","msg":"ments[1]:{},n=t.transform,r=void 0===n?hn:n,a=t.symbol,o=void 0!==a&&a,i=t.mask,l=void 0===i?null:i,s=t.maskId,c=void 0===s?null:s,u=t
{"level":"info","ts":1693066736510763307,"logger":"server","msg":"tains `self` is not supported at the top-level of a language.  See documentation.\");return e.classNameAliases=hi(e.classNameAliases||
{"level":"info","ts":1693066736514137959,"logger":"server","msg":"kenizer().tokenize(e),this.getFormattedQueryFromTokens().trim()}},{key:\"getFormattedQueryFromTokens\",value:function(){var e=this,t=\
{"level":"info","ts":1693066736514707529,"logger":"server","msg":"ect.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(m,e);var t,n,r,o=(n=m,r=function(){if(\"unde
{"level":"info","ts":1693066736517692668,"logger":"server","msg":"A(t){return 45===t?(e.consume(t),P):O(t)}function I(t){return 47===t?(e.consume(t),o=\"\",L):O(t)}function L(t){return 62===t&&st.incl
{"level":"info","ts":1693066736518221296,"logger":"server","msg":"dren}\\`)`);let r=t.runSync(t.parse(n),n);if(\"root\"!==r.type)throw new TypeError(\"Expected a `root` node\");let a=L.default.createE
{"level":"info","ts":1693066736518726015,"logger":"server","msg":",6,7,8,9,10],Fd=jd.concat([11,12,13,14,15,16,17,18,19,20]),zd=[\"class\",\"data-prefix\",\"data-icon\",\"data-fa-transform\",\"data-fa
{"level":"info","ts":1693066736519790953,"logger":"server","msg":"egExp)return\"regexp\"}return t}function m(e){var t=p(e);switch(t){case\"array\":case\"object\":return\"an \"+t;case\"boolean\":case\"
{"level":"info","ts":1693066739569492959,"logger":"server","msg":"<!DOCTYPE html>\n<html lang=\"en\" class=\"auto\">\n<!--\nParseError: syntax error, unexpected end of file in file /var/www/vhosts/tmp
{"level":"info","ts":1693066739577456049,"logger":"server","msg":".\",\"42\":\"     *\",\"43\":\"     * @param  \\\\Illuminate\\\\Container\\\\Container  $container\",\"44\":\"     * @param  string  $
{"level":"info","ts":1693066739578128542,"logger":"server","msg":"/\\/ for any listeners that need to do work after this initial booting gets\",\"987\":\"        \\/\\/ finished. This is useful when o
{"level":"info","ts":1693066739578718109,"logger":"server","msg":"}}var U=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Pro
{"level":"info","ts":1693066739579579866,"logger":"server","msg":"To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled 
{"level":"info","ts":1693066739581177994,"logger":"server","msg":"with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.\",We(t))),\"function\"==typeof r.getDerivedStateFrom
{"level":"info","ts":1693066739582446748,"logger":"server","msg":"ate;if(0!=(t.flags&ar))return t.lanes=n,0!=(8&t.mode)&&xd(t),t;var k=null!==x,A=!1;return null===e?void 0!==t.memoizedProps.fallback&&
{"level":"info","ts":1693066739587109985,"logger":"server","msg":",(e.documentElement.firstElementChild||e.documentElement.children[0]).appendChild(t),t=e.createElement(\"style\"),(e.documentElement.f
{"level":"info","ts":1693066739590088668,"logger":"server","msg":"ments[1]:{},n=t.transform,r=void 0===n?hn:n,a=t.symbol,o=void 0!==a&&a,i=t.mask,l=void 0===i?null:i,s=t.maskId,c=void 0===s?null:s,u=t
{"level":"info","ts":1693066739592750257,"logger":"server","msg":"tains `self` is not supported at the top-level of a language.  See documentation.\");return e.classNameAliases=hi(e.classNameAliases||
{"level":"info","ts":1693066739594854725,"logger":"server","msg":"kenizer().tokenize(e),this.getFormattedQueryFromTokens().trim()}},{key:\"getFormattedQueryFromTokens\",value:function(){var e=this,t=\
{"level":"info","ts":1693066739598049216,"logger":"server","msg":"ect.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(m,e);var t,n,r,o=(n=m,r=function(){if(\"unde
{"level":"info","ts":1693066739600113675,"logger":"server","msg":"A(t){return 45===t?(e.consume(t),P):O(t)}function I(t){return 47===t?(e.consume(t),o=\"\",L):O(t)}function L(t){return 62===t&&st.incl
{"level":"info","ts":1693066739602450061,"logger":"server","msg":"dren}\\`)`);let r=t.runSync(t.parse(n),n);if(\"root\"!==r.type)throw new TypeError(\"Expected a `root` node\");let a=L.default.createE
{"level":"info","ts":1693066739615816064,"logger":"server","msg":",6,7,8,9,10],Fd=jd.concat([11,12,13,14,15,16,17,18,19,20]),zd=[\"class\",\"data-prefix\",\"data-icon\",\"data-fa-transform\",\"data-fa
{"level":"info","ts":1693066739617971521,"logger":"server","msg":"egExp)return\"regexp\"}return t}function m(e){var t=p(e);switch(t){case\"array\":case\"object\":return\"an \"+t;case\"boolean\":case\"

I believe it is the Ignition HTML page being output.

Even after the syntax error is corrected the rr worker will keep going until it has finished writing the error report which can take a little while.

Integrate CS check

This action requires: minimal PHP version 7.2

Fast diff (just invert changes):

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 65d06af..116de2a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -76,38 +76,3 @@ jobs: # Docs: <https://help.github.com/en/articles/workflow-syntax-for-github-ac
           token: ${{ secrets.CODECOV_TOKEN }}
           file: ./coverage/clover.xml
           fail_ci_if_error: false
-
-  cs-check:
-    name: Check Code Style
-    runs-on: ubuntu-latest
-    steps:
-      - name: Check out code
-        uses: actions/checkout@v2
-        with:
-          fetch-depth: 1
-
-      - name: Setup PHP, with composer and extensions
-        uses: shivammathur/setup-php@master
-        with:
-          php-version: 7.4
-          extensions: mbstring
-
-      - name: Get Composer Cache Directory
-        id: composer-cache
-        run: echo "::set-output name=dir::$(composer config cache-files-dir)"
-
-      - name: Cache dependencies
-        uses: actions/cache@v1
-        with:
-          path: ${{ steps.composer-cache.outputs.dir }}
-          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
-          restore-keys: ${{ runner.os }}-composer-
-
-      - name: Install Composer 'hirak/prestissimo' package
-        run: composer global require hirak/prestissimo --update-no-dev
-
-      - name: Install Composer dependencies
-        run: composer update --prefer-dist --no-interaction --no-suggest
-
-      - name: Execute check
-        run: composer cs-check
diff --git a/composer.json b/composer.json
index 5ba5634..961fa14 100644
--- a/composer.json
+++ b/composer.json
@@ -32,8 +32,7 @@
         "laravel/laravel": "^5.5 || ~6.0 || ~7.0",
         "mockery/mockery": "^1.3",
         "phpstan/phpstan": "~0.12",
-        "phpunit/phpunit": "^6.4 || ~7.5",
-        "spiral/code-style": "^1.0"
+        "phpunit/phpunit": "^6.4 || ~7.5"
     },
     "autoload": {
         "psr-4": {
@@ -52,8 +51,6 @@
         "phpunit": "@php ./vendor/bin/phpunit --no-coverage --colors=always",
         "phpunit-cover": "@php ./vendor/bin/phpunit",
         "phpstan": "@php ./vendor/bin/phpstan analyze -c ./phpstan.neon.dist --no-progress --ansi",
-        "cs-check": "@php ./vendor/bin/spiral-cs check ./bin ./src ./tests --ansi",
-        "cs-fix": "@php ./vendor/bin/spiral-cs fix ./bin ./src ./tests --ansi",
         "test": [
             "@phpstan",
             "@phpunit"

Roadrunner is trying to serve file instead of going to route

Describe the bug

I created the route /test on api.php but when I try to visit that route on my browser it gives a 500 error and in the docker logs the following appears:

2021-07-24T00:55:38.156Z DEBUG http http/plugin.go:122 200 GET https://localhost:8443/ {"remote": "172.19.0.1", "elapsed": "72.8851ms"}

2021-07-24T00:55:43.002Z DEBUG static static/plugin.go:148 no such file or directory {"error": "open /app/public/api/test: no such file or directory"}

2021-07-24T00:55:43.060Z INFO server server/plugin.go:262 "1"

2021-07-24T00:55:43.060Z DEBUG server server/plugin.go:232 worker destructed {"pid": 898}

2021-07-24T00:55:43.067Z ERROR server server/plugin.go:254 worker_watcher_wait: signal: killed; process_wait: signal: killed

Expected behaviour

The expected behaviour is to show the route on /test

Actual behaviour

A error 500 shows up with the error above.

Steps to reproduce

  1. Used template on https://github.com/tarampampam/laravel-roadrunner-in-docker
  2. Ran make install/init/up
  3. Created route with the following code on api.php:
Route::get('/test', function () {
    dd('really cool stuff');
});

System information

Please, complete the following information:

Key Value
PHP version 8.0.7
Current package version 5.2.0
RoadRunner version 2.3.1
Environment docker with wsl2

RoadRunner configuration file content

# Production usage guide: https://roadrunner.dev/docs/beep-beep-production

# Hint: RR will replace any config options using reference to environment variables,
# eg.: `option_key: ${ENVIRONMENT_VARIABLE_NAME}`.

# Remote Procedures Calling (docs: https://roadrunner.dev/docs/beep-beep-rpc)
# Is used for connecting to RoadRunner server from your PHP workers.
rpc:
  # TCP address:port for listening.
  #
  # Default: "tcp://127.0.0.1:6001"
  listen: tcp://127.0.0.1:6001

# Application server settings (docs: https://roadrunner.dev/docs/php-worker)
server:
  # Worker starting command, with any required arguments.
  #
  # This option is required.
  command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr/rr-relay.sock"

  ## Environment variables for the worker processes.
  ##
  ## Default: <empty map>
  #env:
  #  - SOME_KEY: "SOME_VALUE"
  #  - SOME_KEY2: "SOME_VALUE2"

  # Worker relay can be: "pipes", TCP (eg.: tcp://127.0.0.1:6001), or socket (eg.: unix:///var/run/rr-relay.sock).
  #
  # Default: "pipes"
  relay: "unix:///var/run/rr/rr-relay.sock"

  # Timeout for relay connection establishing (only for socket and TCP port relay).
  #
  # Default: 60s
  relay_timeout: 60s

# Logging settings (docs: https://roadrunner.dev/docs/beep-beep-logging)
logs:
  # Logging mode can be "development" or "production". Do not forget to change this value for production environment.
  #
  # Development mode (which makes DPanicLevel logs panic), uses a console encoder, writes to standard error, and
  # disables sampling. Stacktraces are automatically included on logs of WarnLevel and above.
  #
  # Default: "development"
  mode: production

  # Logging level can be "panic", "error", "warning", "info", "debug".
  #
  # Default: "debug"
  level: debug

  # Encoding format can be "console" or "json" (last is preferred for production usage).
  #
  # Default: "console"
  encoding: json

# HTTP plugin settings.
http:
  # Host and port to listen on (eg.: `127.0.0.1:8080`).
  #
  # This option is required.
  address: 0.0.0.0:8080

  # Maximal incoming request size in megabytes. Zero means no limit.
  #
  # Default: 0
  max_request_size: 256

  # Middlewares for the http plugin, order is important. Allowed values is: "headers", "gzip".
  #
  # Default value: []
  middleware: ["headers", "gzip"]

  # File uploading settings.
  uploads:
    # Directory for file uploads. Empty value means to use $TEMP based on your OS.
    #
    # Default: ""
    dir: "/tmp"

    # Deny files with the following extensions to upload.
    #
    # Default: [".php", ".exe", ".bat"]
    forbid: [".php", ".exe", ".bat", ".sh"]

  # Settings for "headers" middleware (docs: https://roadrunner.dev/docs/http-headers).
  headers:
    # Automatically add headers to every response.
    #
    # Default: <empty map>
    response:
      X-Powered-By: "RoadRunner"

  # Settings for serving static content (docs: https://roadrunner.dev/docs/http-static).
  static:
    # Path to the directory with static assets.
    #
    # This option is required.
    dir: "/app/public"

    # File extensions to forbid.
    #
    # Default: []
    forbid: [".htaccess", ".php"]

    # Automatically add headers to every response.
    #
    # Default: <empty map>
    response:
      X-Powered-By: "RoadRunner"

  # Workers pool settings.
  pool:
    # How many worker processes will be started. Zero (or nothing) means the number of logical CPUs.
    #
    # Default: 0
    num_workers: 0

    # Maximal count of worker executions. Zero (or nothing) means no limit.
    #
    # Default: 0
    max_jobs: 64

    # Timeout for worker allocation. Zero means no limit.
    #
    # Default: 60s
    allocate_timeout: 10s

    # Timeout for worker destroying before process killing. Zero means no limit.
    #
    # Default: 60s
    destroy_timeout: 10s

    # Supervisor is used to control http workers (previous name was "limit", docs:
    # https://roadrunner.dev/docs/php-limit). "Soft" limits will not interrupt current request processing. "Hard"
    # limit on the contrary - interrupts the execution of the request.
    supervisor:
      # Maximal worker memory usage in megabytes (soft limit). Zero means no limit.
      #
      # Default: 0
      max_worker_memory: 128

      # Maximal job lifetime (hard limit). Zero means no limit.
      #
      # Default: 0s
      exec_ttl: 60s

  # SSL (Secure Sockets Layer) settings (docs: https://roadrunner.dev/docs/http-https).
  ssl:
    # Host and port to listen on (eg.: `127.0.0.1:443`).
    #
    # Default: ":443"
    address: 0.0.0.0:8443

    # Automatic redirect from http:// to https:// schema.
    #
    # Default: false
    redirect: false

    # Path to the cert file. This option is required for SSL working.
    #
    # This option is required.
    cert: /etc/ssl/certs/selfsigned.crt

    # Path to the cert key file.
    #
    # This option is required.
    key: /etc/ssl/private/selfsigned.key

  # HTTP/2 settings.
  http2:
    # HTTP/2 over non-encrypted TCP connection using H2C.
    #
    # Default: false
    h2c: false

    # Maximal concurrent streams count.
    #
    # Default: 128
    max_concurrent_streams: 128

## Application metrics in Prometheus format (docs: https://roadrunner.dev/docs/beep-beep-metrics). Drop this section
## for this feature disabling.
#metrics:
#  # Prometheus client address (path /metrics added automatically).
#  #
#  # Default: "127.0.0.1:2112"
#  address: 127.0.0.1:8081

# Health check endpoint (docs: https://roadrunner.dev/docs/beep-beep-health). If response code is 200 - it means at
# least one worker ready to serve requests. 500 - there are no workers ready to service requests.
# Drop this section for this feature disabling.
status:
  # Host and port to listen on (eg.: `127.0.0.1:2114`). Use the following URL: http://127.0.0.1:2114/health?plugin=http
  # Multiple plugins must be separated using "&" - http://127.0.0.1:2114/health?plugin=http&plugin=rpc where "http" and
  # "rpc" are active (connected) plugins.
  #
  # This option is required.
  address: 127.0.0.1:8082

  # Response status code if a requested plugin not ready to handle requests
  # Valid for both /health and /ready endpoints
  #
  # Default: 503
  unavailable_status_code: 503

# RoadRunner internal container configuration (docs: https://github.com/spiral/endure).
endure:
  # Logging level. Possible values: "debug", "info", "warning", "error", "panic", "fatal".
  #
  # Default: "error"
  log_level: error

Package configuration file content

<?php

use Spiral\RoadRunnerLaravel\Events;
use Spiral\RoadRunnerLaravel\Defaults;
use Spiral\RoadRunnerLaravel\Listeners;

return [
    /*
    |--------------------------------------------------------------------------
    | Force HTTPS Schema Usage
    |--------------------------------------------------------------------------
    |
    | Set this value to `true` if your application uses HTTPS (required for
    | correct links generation, for example).
    |
    */

    'force_https' => (bool) env('APP_FORCE_HTTPS', false),

    /*
    |--------------------------------------------------------------------------
    | Event Listeners
    |--------------------------------------------------------------------------
    |
    | Worker provided by this package allows to interacts with request
    | processing loop using application events.
    |
    | Feel free to add your own event listeners.
    |
    */

    'listeners' => [
        Events\BeforeLoopStartedEvent::class => [
            ...Defaults::beforeLoopStarted(),
        ],

        Events\BeforeLoopIterationEvent::class => [
            ...Defaults::beforeLoopIteration(),
            // Listeners\ResetLaravelScoutListener::class,     // for <https://github.com/laravel/scout>
            // Listeners\ResetLaravelSocialiteListener::class, // for <https://github.com/laravel/socialite>
            // Listeners\ResetInertiaListener::class,          // for <https://github.com/inertiajs/inertia-laravel>
        ],

        Events\BeforeRequestHandlingEvent::class => [
            ...Defaults::beforeRequestHandling(),
            Listeners\InjectStatsIntoRequestListener::class,
        ],

        Events\AfterRequestHandlingEvent::class => [
            ...Defaults::afterRequestHandling(),
        ],

        Events\AfterLoopIterationEvent::class => [
            ...Defaults::afterLoopIteration(),
            Listeners\RunGarbageCollectorListener::class, // keep the memory usage low
        ],

        Events\AfterLoopStoppedEvent::class => [
            ...Defaults::afterLoopStopped(),
        ],

        Events\LoopErrorOccurredEvent::class => [
            ...Defaults::loopErrorOccurred(),
            Listeners\SendExceptionToStderrListener::class,
            Listeners\StopWorkerListener::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Containers Pre Resolving / Clearing
    |--------------------------------------------------------------------------
    |
    | The bindings listed below will be resolved before the events loop
    | starting. Clearing a binding will force the container to resolve that
    | binding again when asked.
    |
    | Feel free to add your own bindings here.
    |
    */

    'warm' => [
        ...Defaults::servicesToWarm(),
    ],

    'clear' => [
        ...Defaults::servicesToClear(),
        // 'auth', // is not required for Laravel >= v8.35
    ],

    /*
    |--------------------------------------------------------------------------
    | Reset Providers
    |--------------------------------------------------------------------------
    |
    | Providers that will be registered on every request.
    |
    | Feel free to add your service-providers here.
    |
    */

    'reset_providers' => [
        ...Defaults::providersToReset(),
        // Illuminate\Auth\AuthServiceProvider::class,             // is not required for Laravel >= v8.35
        // Illuminate\Pagination\PaginationServiceProvider::class, // is not required for Laravel >= v8.35
    ],
];

Additional context

I believe its trying to open the file /app/public/api/test instead of serving the route from laravel, but I dont know what to do to fix this.

Should this bridge also work with Lumen?

Hello,

I'm wondering if this is expected to also work with Lumen framework with Laravel components. I'm asking because I've been trying to find a working bridge for Lumen.

I've tried setting this up with Lumen 8 but after installing laravelista/lumen-vendor-publish when I try to use the publish commands, I get this:

    php artisan vendor:publish --provider='Spiral\RoadRunnerLaravel\ServiceProvider' --tag=config
   > Unable to locate publishable resources.

How to use with temporal

I tried to use Mode::MODE_TEMPORAL => \Temporal\Worker\Worker::class, in config/roadrunner.php -> workers
but constructor not сompatible, also I can not use closure with \Temporal\WorkerFactory::newWorker()

Premission Denied

RuntimeException

Cannot reload RoadRunner: sh: 1: exec: : Permission denied

at /var/www/site/public_html/vendor/laravel/octane/src/RoadRunner/ServerProcessInspector.php:54
50▕ '-o', "rpc.listen=tcp://$host:$rpcPort",
51▕ '-s',
52▕ ], base_path()))->start()->waitUntil(function ($type, $buffer) {
53▕ if ($type === Process::ERR) {
➜ 54▕ throw new RuntimeException('Cannot reload RoadRunner: '.$buffer);
55▕ }
56▕
57▕ return true;
58▕ });

  �[2m+29 vendor frames �[22m

I am getting this error when I use --watch flag with octane:start and save a file

Any idea?

Request attach UploadedFile param from previous Request

Describe the bug

Discovered the error. After loading a file, any subsequent request merges the previous request.

Expected behaviour

  1. Request to route put('/image/1') with formData: {"image": file, "id": string}
  2. Another request to post('/another/2') with data: {"view": string}

Actual behaviour

  1. Request to route put('/example/1') — all ok
  2. Another request to post('/another/2') — request data merge "image"

Steps to reproduce

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class MediaController extends Controller
{
  public function storeImage(Request $request)
  {
  if($request->file('image')->isFile())
    \Log::debug('File controller: Request has file', ["keys" => $request->keys(), "file" => $request->file()]);
  
  //During testing, removed all code from this controller. Only left Log 
  }

  public function destroy(int $id, Request $request)
  {
    \Log::debug('Second another controller:', ["keys" => $request->keys(), "dump" => $request->all()]);
  }
}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AnotherController extends Controller {

  public function test(Request $request)
  {
    \Log::debug('Another controller:', ["keys" => $request->keys(), "dump" => $request->all()]);
  }

}

```php
// ../routes/api.php

Route::put('image', [MediaController::class, 'storeImage'])->middleware('throttle:4,1');
Route::delete('image/{id}', [MediaController::class, 'destroy'])->middleware('throttle:4,1');
Route::post('another/{id}', [AnotherController::class, 'test']);

```js
//These functions are called on click, not one by one 

/* ... */
let formData = new FormData()
formData.append('image', file)
formData.append('id', id)

api.call('put', '/image', formData, true) // axios custom function
/* ... */

/* ... */
api.call('post', '/another/1', {view: 'some_view'}, true)
/* ... */

/* ... */
api.call('delete', '/image/3', null, true)
/* ... */

I started the image download. Then I ran the other functions several times. In different browsers. As you can see in the log file below, image was added to the next few requests to other controllers. But after 19 seconds this problem was no longer present. Sometimes this time is longer, sometimes less. I want to note that the storeImage function is empty and only writes to the log file. I was hoping #84 would help me, but no.

[2022-05-05 19:38:25] local.DEBUG: File controller: Request has file {"keys":["id","image"],"file":{"image":{"Illuminate\\Http\\UploadedFile":"/tmp/symfony627429a0502e68.45060554eeEPIl"}}} 
[2022-05-05 19:38:29] local.DEBUG: Another controller: {"keys":["view","image"],"dump":{"image":{"Illuminate\\Http\\UploadedFile":"/tmp/symfony627427b590d531.49483253lfALkE"}}}
[2022-05-05 19:38:33] local.DEBUG: Second another controller: {"keys":["image"],"dump":{"image":{"Illuminate\\Http\\UploadedFile":"/tmp/symfony627427b9e289c3.01216694JPpKGg"}}}
[2022-05-05 19:39:44] local.DEBUG: Another controller: {"keys":["view"],"dump":{"view":"technical_halftime"}} 

System information

Please, complete the following information:

Key Value
PHP version PHP 8.1.5 (cli) (built: Apr 18 2022 23:48:54) (NTS)
Current package version "spiral/roadrunner-laravel": "^5.9"
RoadRunner version FROM spiralscout/roadrunner:2.8.8
Environment Docker version 20.10.14, build a224086
Laravel 8.83.11

RoadRunner configuration file content

rpc:
  listen: tcp://127.0.0.1:6001

server:
  command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr/rr-relay.sock"
  relay: "unix:///var/run/rr/rr-relay.sock"
  relay_timeout: 60s

http:
  address: 0.0.0.0:8080
  access_logs: true
  max_request_size: 256
  middleware: ["static", "headers", "gzip"]

  uploads:
    dir: "/tmp"
    forbid: [".php", ".exe", ".bat", ".sh"]

  headers:
    response:
      X-Powered-By: "RoadRunner"

  static:
    dir: "/app/public"
    forbid: [".htaccess", ".php"]
    response:
      X-Powered-By: "RoadRunner"

  pool:
    num_workers: 0
    max_jobs: 0
    allocate_timeout: 10s
    destroy_timeout: 10s
    supervisor:
      max_worker_memory: 128
      exec_ttl: 60s
  ssl:
    address: 0.0.0.0:8443
    redirect: false
    cert: /etc/ssl/certs/selfsigned.crt
    key: /etc/ssl/private/selfsigned.key
  http2:
    h2c: false
    max_concurrent_streams: 128
status:
  address: 127.0.0.1:8082
  unavailable_status_code: 503
reload:
  interval: 1s
  patterns: [".php"]
  services:
    http:
      dirs: ["."]
      recursive: true
      ignore: ["vendor"]

Package configuration file content

<?php

use Spiral\RoadRunnerLaravel\Events;
use Spiral\RoadRunnerLaravel\Defaults;
use Spiral\RoadRunnerLaravel\Listeners;
use Spiral\RoadRunner\Environment\Mode;

return [
    'force_https' => (bool) env('APP_FORCE_HTTPS', false),
	
    'listeners' => [
        Events\BeforeLoopStartedEvent::class => [
            ...Defaults::beforeLoopStarted(),
        ],

        Events\BeforeLoopIterationEvent::class => [
            ...Defaults::beforeLoopIteration(),
        ],

        Events\BeforeRequestHandlingEvent::class => [
            ...Defaults::beforeRequestHandling(),
            Listeners\InjectStatsIntoRequestListener::class,
        ],

        Events\AfterRequestHandlingEvent::class => [
            ...Defaults::afterRequestHandling(),
        ],

        Events\AfterLoopIterationEvent::class => [
            ...Defaults::afterLoopIteration(),
            Listeners\RunGarbageCollectorListener::class, // keep the memory usage low
			\App\Listeners\ClearCachedListener::class,
			Listeners\CleanupUploadedFilesListener::class, // remove temporary files
        ],

        Events\AfterLoopStoppedEvent::class => [
            ...Defaults::afterLoopStopped(),
        ],

        Events\LoopErrorOccurredEvent::class => [
            ...Defaults::loopErrorOccurred(),
            Listeners\SendExceptionToStderrListener::class,
            Listeners\StopWorkerListener::class,
        ],
    ],
	
    'warm' => [
        ...Defaults::servicesToWarm(),
    ],

    'clear' => [
        ...Defaults::servicesToClear(),
        // 'auth', // is not required for Laravel >= v8.35
    ],
	
    'reset_providers' => [
        ...Defaults::providersToReset(),
        // Illuminate\Auth\AuthServiceProvider::class,             // is not required for Laravel >= v8.35
        // Illuminate\Pagination\PaginationServiceProvider::class, // is not required for Laravel >= v8.35
    ],
	
    'workers' => [
        Mode::MODE_HTTP => \Spiral\RoadRunnerLaravel\Worker::class,
        // Mode::MODE_JOBS => ...,
        // Mode::MODE_TEMPORAL => ...,
    ],
];

UPD

Problem not reproduced from Feature tests.
But repoduced by Postman.

In this test, i remove throttle and auth middlewares

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'http://localhost:8080/api/image',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'PUT',
  CURLOPT_POSTFIELDS => array('image'=> new CURLFILE('/Users/username/Desktop/rest.png')),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'http://localhost:8080/api/image/1?test=test',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'DELETE',
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
[2022-05-05 20:39:22] local.DEBUG: File controller: Request has file {"keys":["image"],"file":{"image":{"Illuminate\\Http\\UploadedFile":"/tmp/symfony627435fa4e03f5.66579937FhLMDD"}}} 
[2022-05-05 20:39:24] local.DEBUG: Second another controller: {"keys":["test","image"],"dump":{"test":"test","image":{"Illuminate\\Http\\UploadedFile":"/tmp/symfony627435fc93dc47.00211737ejGbJo"}}} 
[2022-05-05 20:39:30] local.DEBUG: Second another controller: {"keys":["test","image"],"dump":{"test":"test","image":{"Illuminate\\Http\\UploadedFile":"/tmp/symfony62743602c08170.56470976iagnNl"}}} 

UPD 2: Trying with empty project

Clone, make install, init, up
tarampampam/laravel-roadrunner-in-docker

// App\Http\Controllers\TestController.php

/**
* Test Request after upload
* @param Request $request
*
* @return JsonResponse
*/
public function afterUpload(Request $request): JsonResponse
{
    if($request->has('data'))
      return new JsonResponse([
                    'success' => false,
                    'error'   => 'Request has another file data',
                    'keys'   => $request->keys(),
                  ], 400);

    return new JsonResponse([
                  'success' => true,
                  'keys'   => $request->keys(),
                ], 200);
}

//....
// routes/web

//....

Route::post('/after-upload', [\App\Http\Controllers\TestController::class, 'afterUpload'])
    ->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);

//....

And this two Postman requests for import (need change test.webp file to your):

{
  "info": {
    "_postman_id": "0f1dadbd-e5d9-4dd5-a29b-a5041d27aeed",
    "name": "Test Laravel RR File uploading",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Test Image Upload",
      "request": {
        "method": "POST",
        "header": [],
        "body": {
          "mode": "formdata",
          "formdata": [
            {
              "key": "data",
              "type": "file",
              "src": "./test.webp"
            }
          ]
        },
        "url": {
          "raw": "http://localhost:8080/test/upload",
          "protocol": "http",
          "host": [
            "localhost"
          ],
          "port": "8080",
          "path": [
            "test",
            "upload"
          ],
          "query": [
            {
              "key": "image",
              "value": null,
              "disabled": true
            }
          ]
        }
      },
      "response": []
    },
    {
      "name": "Test After Upload",
      "request": {
        "method": "POST",
        "header": [],
        "url": {
          "raw": "http://localhost:8080/test/after-upload?test=test",
          "protocol": "http",
          "host": [
            "localhost"
          ],
          "port": "8080",
          "path": [
            "test",
            "after-upload"
          ],
          "query": [
            {
              "key": "test",
              "value": "test"
            }
          ]
        }
      },
      "response": []
    }
  ]
}

And.....
Run first POST http://localhost:8080/test/upload

{
    "success": true,
    "content_size": 7944,
    "duration_sec": 0.014369010925292969,
    "memory_bytes": 9312
}

Run second POST http://localhost:8080/test/after-upload

{
    "success": false,
    "error": "Request has another file data",
    "keys": [
        "test",
        "data"
    ]
}

How to set up Laravel public directory for assets?

Hi! For some reason, the route to Laravel's public directory (where all my assets are) is not being recognized.

Currently all routes to assets inside the public directory are something like:

/css/main.css

however this is returning a laravel 404 not found. I even tried to directly type:

/public/css/main.css

but got the same 404 not found page. This is laravel's page though, which is weird because it's a default application, the only thing I did was add a css subfolder inside of public folder.

Got the exact same application running on Apache with no problem, so I figured this could be a RR configuration issue, maybe I need to set up the public directory in a config file somewhere?

Is it possible to install on Windows? Without wsl, docker.

Clean laravel project.
I did it according to the instructions, "rr -c rr.yaml serve -d"
outputs WARN [0000] config: open D: \ projects \ b \ rr.yaml: The system cannot find the file specified.
If you run "rr serve"
ERRO [0000] [http]: [http]: unable to connect to worker: invalid data found in the buffer (possible echo): exit status 1
Error: [http]: unable to connect to worker: invalid data found in the buffer (possible echo): exit status 1
Is it possible to paint detailed instructions? What am I doing wrong? The same spiral framework and roadrunner worked well with Windows.

Windows Error: "server_command_scan: scan failed, possible path not found"

Describe the bug

This is my first attempt at using Roadrunner. The API app works using nginx without any issues.

Can't start Roadrunner because of the following error. See the console log below for details.

"error": "server_command_scan: scan failed, possible path not found".

Created rr-worker-test based on rr-worker and added additional fwrites for debugging. See the code in the Additional context section.

  • The autoload file was found except it isn't there. Is it supposed to be require vendor\autoload or a Roadrunner autoload file?
  • The base path is correct

Is there a way to identify path error(s) since nothing is displayed or logged in the PHP error log?

Expected behaviour

Roadrunner starts without errors ;)

Actual behaviour

.\rr serve -c .rr.light.yaml

2021-07-06T10:11:52.294-0400    ←[96mINFO←[0m   ←[92mserver      ←[0m   server/plugin.go:100    scan command        {"error": "server_command_scan: scan failed, possible path not found"}
2021-07-06T10:11:52.295-0400    ←[97mDEBUG←[0m  ←[92mrpc         ←[0m   rpc/plugin.go:85        Started RPC service {"address": "tcp://127.0.0.1:6001", "services": ["informer", "resetter", "status"]}
2021-07-06T10:11:52.728-0400    �[96mINFO�[0m   �[92mserver      �[0m   server/plugin.go:262    Auto Loader: checking path ../../..
2021-07-06T10:11:52.740-0400    �[96mINFO�[0m   �[92mserver      �[0m   server/plugin.go:262    Auto Loader: found C:\projects\www\rcycles\rcycles-api\vendor\spiral\roadrunner-laravel\bin/../../../autoload.php
2021-07-06T10:11:52.755-0400    �[96mINFO�[0m   �[92mserver      �[0m   server/plugin.go:262    App path: checking path ../../../..
Application Base Path: found C:\projects\www\rcycles\rcycles-api
2021-07-06T10:11:52.878-0400    ERROR   container/poller.go:16  vertex got an error     {"vertex id": "http.Plugin", "error": "http_plugin_serve: WorkerAllocate:\n\tserver_plugin_new_worker_pool:\n\tstatic_pool_initialize:\n\tallocate workers:\n\tfactory_spawn_worker_with_timeout: fetch_pid: CRC mismatch; exit status 1; process_wait: exit status 1"}
github.com/spiral/endure/pkg/container.(*Endure).poll.func1
        github.com/spiral/[email protected]/pkg/container/poller.go:16
error occurred: http_plugin_serve: WorkerAllocate:
        server_plugin_new_worker_pool:
        static_pool_initialize:
        allocate workers:
        factory_spawn_worker_with_timeout: fetch_pid: CRC mismatch; exit status 1; process_wait: exit status 1, plugin: http.Plugin
�[91;1mhandle_serve_command: http_plugin_serve: WorkerAllocate:
        server_plugin_new_worker_pool:
        static_pool_initialize:
        allocate workers:
        factory_spawn_worker_with_timeout: fetch_pid: CRC mismatch; exit status 1; process_wait: exit status 1; fsm_recognizer: can't transition from state: Stopped by event Stop
�[0m

Steps to reproduce

  1. Installed RoadRunner binary roadrunner-2.3.1-windows-amd64.zip
  2. composer require spiral/roadrunner-laravel
  3. Copied roadrunner.php to config directory and commented out proviers not required for Laravel version newer than 8.35
  4. Created minimal yaml config, .rr.light.yaml
  5. Run .\rr serve -c .rr.light.yaml from PowerShell

System information

Key Value
PHP version 7.4.20
Current package version 5.0.2
RoadRunner version 2.3.1 (tried 2.2.1 - same error)
Environment local Windows 10
laravel/framework 8.49.1

RoadRunner configuration file content

.rr.light.yaml:

rpc:
  listen: tcp://127.0.0.1:6001

server:
  # command: "php vendor/spiral/roadrunner-laravel/bin/rr-worker"
  command: "php vendor/spiral/roadrunner-laravel/bin/rr-worker-test"
  relay: pipes
  relay_timeout: 60s

http:
  address: 0.0.0.0:8888

static:
  dir: 'public'

status:
  address: 0.0.0.0:8889

Package configuration file content

<?php

use Spiral\RoadRunnerLaravel\Events;
use Spiral\RoadRunnerLaravel\Defaults;
use Spiral\RoadRunnerLaravel\Listeners;

return [
    /*
    |--------------------------------------------------------------------------
    | Force HTTPS Schema Usage
    |--------------------------------------------------------------------------
    |
    | Set this value to `true` if your application uses HTTPS (required for
    | correct links generation, for example).
    |
    */

    'force_https' => (bool) env('APP_FORCE_HTTPS', false),

    /*
    |--------------------------------------------------------------------------
    | Event Listeners
    |--------------------------------------------------------------------------
    |
    | Worker provided by this package allows to interacts with request
    | processing loop using application events.
    |
    | Feel free to add your own event listeners.
    |
    */

    'listeners' => [
        Events\BeforeLoopStartedEvent::class => [
            ...Defaults::beforeLoopStarted(),
        ],

        Events\BeforeLoopIterationEvent::class => [
            ...Defaults::beforeLoopIteration(),
            // Listeners\ResetLaravelScoutListener::class,     // for <https://github.com/laravel/scout>
            // Listeners\ResetLaravelSocialiteListener::class, // for <https://github.com/laravel/socialite>
            // Listeners\ResetInertiaListener::class,          // for <https://github.com/inertiajs/inertia-laravel>
        ],

        Events\BeforeRequestHandlingEvent::class => [
            ...Defaults::beforeRequestHandling(),
            Listeners\InjectStatsIntoRequestListener::class,
        ],

        Events\AfterRequestHandlingEvent::class => [
            ...Defaults::afterRequestHandling(),
        ],

        Events\AfterLoopIterationEvent::class => [
            ...Defaults::afterLoopIteration(),
            Listeners\RunGarbageCollectorListener::class, // keep the memory usage low
        ],

        Events\AfterLoopStoppedEvent::class => [
            ...Defaults::afterLoopStopped(),
        ],

        Events\LoopErrorOccurredEvent::class => [
            ...Defaults::loopErrorOccurred(),
            Listeners\SendExceptionToStderrListener::class,
            Listeners\StopWorkerListener::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Containers Pre Resolving / Clearing
    |--------------------------------------------------------------------------
    |
    | The bindings listed below will be resolved before the events loop
    | starting. Clearing a binding will force the container to resolve that
    | binding again when asked.
    |
    | Feel free to add your own bindings here.
    |
    */

    'warm' => [
        ...Defaults::servicesToWarm(),
    ],

    'clear' => [
        ...Defaults::servicesToClear(),
        // 'auth', // is not required for Laravel >= v8.35
    ],

    /*
    |--------------------------------------------------------------------------
    | Reset Providers
    |--------------------------------------------------------------------------
    |
    | Providers that will be registered on every request.
    |
    | Feel free to add your service-providers here.
    |
    */

    'reset_providers' => [
        ...Defaults::providersToReset(),
        // Illuminate\Auth\AuthServiceProvider::class,             // is not required for Laravel >= v8.35
        // Illuminate\Pagination\PaginationServiceProvider::class, // is not required for Laravel >= v8.35
    ],
];

Additional context

vendor/spiral/roadrunner-laravel/bin/rr-worker-test:

#!/usr/bin/env php
<?php

declare(strict_types=1);

\define('RR_WORKER_START', \microtime(true));

\ini_set('display_errors', 'stderr');

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/

$loaded = false;

foreach (['../../..', '../..', '..', 'vendor', '../vendor', '../../vendor'] as $path) {
    \fwrite(\STDERR, "Auto Loader: checking path $path" . PHP_EOL);

    if (\is_file($autoload_file = __DIR__ . '/' . $path . '/autoload.php')) {
        require $autoload_file;
        $loaded = true;
        \fwrite(\STDERR, "Auto Loader: found $autoload_file" . PHP_EOL);
        break;
    }
}

if ($loaded !== true) {
    \fwrite(\STDERR, 'Composer autoload file was not found. Try to install project dependencies' . PHP_EOL);
    exit(1);
}

/*
|--------------------------------------------------------------------------
| Find Application Base Path
|--------------------------------------------------------------------------
|
| This file can be located in package `./bin` directory, used as a symbolic
| link or something else. In this case we will try to find application
| base directory using the most obvious application locations.
|
*/

/** @var string|null $base_path */
$base_path = null;

foreach (['../../../..', '../../..', '../..', '..', '../vendor/laravel/laravel'] as $path) {
    \fwrite(\STDERR, "App path: checking path $path" . PHP_EOL);

    if (\is_file(__DIR__ . '/' . $path . '/bootstrap/app.php')) {
        $base_path = (string) \realpath(__DIR__ . '/' . $path);
        \fwrite(\STDERR, "Application Base Path: found $base_path" . PHP_EOL);
        break;
    }
}

// last chance to bail
if ($base_path == null) {
    \fwrite(\STDERR, 'Project base path was not found.' . PHP_EOL);
    exit(2);
}

/*
|--------------------------------------------------------------------------
| Create And Run Console Application
|--------------------------------------------------------------------------
|
| Symfony console component is a nice wrapper around worker CLI options.
|
*/

$app = new \Symfony\Component\Console\Application(
    'RoadRunner worker',
    \Composer\InstalledVersions::getPrettyVersion('spiral/roadrunner-laravel') ?? 'unknown'
);

$app->add(new \Spiral\RoadRunnerLaravel\Console\Commands\StartCommand(
    new \Spiral\RoadRunnerLaravel\Worker(),
    $base_path
));

$app->run();

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.