UPDG/roadrunner-laravel

Problems with laravel

Opened this issue · 7 comments

  1. create new laravel project,i test laravel5.5 laravel 5.7 and laravel 5.8
  2. config db connection
  3. php artisan make:auth
  4. open http://localhost/login,and then refresh this page many times.only refresh,Do nothing others.
  5. use mail and password to login in this page.Under normal circumstances, enter the wrong username and password page will return the prompt "These credentials do not match our records.", but the wrong username and password will not return any information after you refresh the page. Including the wrong username automatically The record is also lost

Looks like there is a problem with the session,May have this problem in all versions of laravel, I only tested 5.5 5.7 5.8

I will continue to test the more detailed questions.

After a series of breakpoint tests, I found the shortest starting code as follows:

Route::get('/', function () {
    \Illuminate\Support\Facades\Session::put("test_session123", time());
    error_log(time());
    $e = session("test_session123");
    error_log(session("test_session123"));
    return view('welcome');
});

The output of error_log is the same twice in each visit to a normal server, but the result is very strange in the rr service using roadrunner-laravel. The result is as follows:
image

I tested the specific code in roadrunner-laravel and found that commenting out resetProvider can respond normally.

...
            $this->_kernel->terminate($request, $response);

//            if (method_exists($this->_app, 'getProvider')) {
//                //reset debugbar if available
//                $this->resetProvider('\Illuminate\Redis\RedisServiceProvider');
//                $this->resetProvider('\Illuminate\Cookie\CookieServiceProvider');
//                $this->resetProvider('\Illuminate\Session\SessionServiceProvider');
//            }
...

The general idea of ​​this place is to force re-registration of the SessionServiceProvider. The idea should be correct, but the re-registered SessionServiceProvider is obviously abnormal. At the same time, I still can't understand why this needs to re-register these ServiceProviders.

I will continue to test more information.

I tested the use of session() and \Illuminate\Support\Facades\Session in the laravel 5.5 framework.

I found that the results of the two methods used in the normal server are the same, but in the service started by roadrunner-laravel, the results of these two methods are different.

The test code is as follows:

$t = time();
// set session use \Illuminate\Support\Facades\Session
\Illuminate\Support\Facades\Session::put("test_session1", $t);
error_log("save_session1:" . $t);
// read session from \Illuminate\Support\Facades\Session and session()
error_log("raea_session11:" . \Illuminate\Support\Facades\Session::get("test_session1"));
error_log("raea_session12:" . session("test_session1"));

// set session use session()
session(["test_session2" => $t]);
error_log("save_session2:" . $t);
// read session from \Illuminate\Support\Facades\Session and session()
error_log("raea_session21:" . \Illuminate\Support\Facades\Session::get("test_session2"));
error_log("raea_session22:" . session("test_session2"));

The results are as follows:
Normal server:
image

RR server:
image

Obviously there is a problem with the session service in the rr server, which may be caused by the different loading methods of session() and \Illuminate\Support\Facades\Session.

Specific reasons to wait for the next test

I tried multiple session() and \Illuminate\Support\Facades\Session startup methods, and finally found a cache-like function in Illuminate\Support\Facades:

protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) {
        return $name;
    }

    if (isset(static::$resolvedInstance[$name])) {
        return static::$resolvedInstance[$name];
    }

    return static::$resolvedInstance[$name] = static::$app[$name];
}

It can reuse objects that have been instantiated before, which causes the re-registration of the SessionServiceProvider in the roadrunner-laravel to fail. Because the first cached object is used when \Illuminate\Support\Facades\Session is used multiple times, then The difference between session() and \Illuminate\Support\Facades\Session

There are two suitable solutions:
Method 1: Stop re-registering SessionServiceProvider in updg\roadrunner\laravel\Bridge,This will make the session work properly.
Method 2: Re-register the SessionServiceProvider in updg\roadrunner\laravel\Bridge to clear the cache of the session in Illuminate\Support\Facades

This approach does not solve all the problems encountered by the session.

\Illuminate\Support\Facades\Facade::clearResolvedInstance("session");

If you see please reply, thank you

+1

I'm having the same problem.

+1

I'm having the same problem.

The laravel framework has not considered multi-connection multiplexing at the beginning of the design. I tried a variety of methods to make the roadrunner perfectly compatible with laravel, including reference https://github.com/swooletw/laravel-swoole/blob/master/config/swoole_http.php#L92-L120 this implementation
But in the end, I found that in any case I had to reinitialize almost all the classes in the next connection to work properly, but in this case it only accelerates laravel for only 10ms, for example php-fpm requires 110ms to load the page to use it. Still need 100ms

This makes me almost give up using the roadrunner to speed up the laravel project.

I solved the problem with sessions (and login) with the following function in the bridge initialization:

$this->app->afterResolving('session.store', function ($session) {
    $this->app['redirect']->setSession($session);
});

Here's my current bridge file:

https://github.com/CubeKode/LaravelPSR7Worker/blob/master/src/Bridge.php

I solved the problem with sessions (and login) with the following function in the bridge initialization:

$this->app->afterResolving('session.store', function ($session) {
    $this->app['redirect']->setSession($session);
});

Here's my current bridge file:

CubeKode/LaravelPSR7Worker:src/Bridge.php@master

I tried this https://github.com/CubeKode/LaravelPSR7Worker/blob/master/src/Bridge.php, the login function seems to work fine, but when another browser opens this page, I automatically log in the same An account.and I can't log out at the same time.

You can only solve part of the session problem, and there are more session exceptions that need to be resolved.