8000 Session changes lost in concurrent requests · Issue #30996 · laravel/framework · GitHub
[go: up one dir, main page]

Skip to content
Session changes lost in concurrent requests  #30996
@trevorgehman

Description

@trevorgehman
  • Laravel Version: 6.9.0
  • PHP Version: 7.3.13
  • Database Driver & Version: Redis

Description:

Since Laravel persists the entire session data array at the end every request, in the case of concurrent requests, any changed session data is very likely to be lost.

// Again, if the session has been configured we will need to close out the session
// so that the attributes may be persisted to some storage medium. We will also
// add the session identifier cookie to the application response headers now.
$this->saveSession($request);

Related issues:

Proposed fixes:

Steps To Reproduce:

In the below example of concurrent requests, the change in Request A will be lost, overridden when StartSession::saveSession($request) is called at the end of Request B's lifecycle:

    |--------  Request A (changes session variable) --------|
|------------ Request B (no changes to session data) ------------|

Recommendation:

The only complete solution to this problem is to use session locking. A package like this one will work: https://github.com/rairlie/laravel-locking-session. However, that basically makes all your AJAX requests synchronous, which isn't a great solution for modern SPA's.

@taylorotwell has mentioned some form of locking as a solution to the problem in #7549 (comment).

However, I do think we can make other improvements. The fact is, most AJAX requests in a modern SPA aren't modifying session data. Nevertheless, they persist the session data at the end of their lifecycle. This means that a single long-running request makes the session data unable to be changed reliably.

After looking at all these related issues and proposed fixes, I think something like this PR #29410 is the most tenable. It basically only persists the session data if it is dirty. It probably could be altered to be enabled/disable through a config option. It doesn't solve the problem if concurrent requests all want to alter the session data, but it does solve the 90% use case where most requests are just reading session data. The one issue I foresee with this approach is session timeout.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0