14
votes

Can someone explain what a session sweeping lottery is? I've attached the default session config file for the Laravel framework.

Questions: 1. It says that some session drivers must manually sweep their storage location. Could someone describe this process and why it is necessary? What session drivers require this action? 2. Why is a lottery necessary? If say some form of storage (database) is full, why does it have to be random? Why can't the framework sweep the old sessions when it detects that the driver is full?

/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/

'lottery' => array(2, 100),
2

2 Answers

12
votes

So, a session is a piece of data that is stored on the server for a certain amount of time.

Imagine using a folder with files to store the sessions. There has to be a moment where the old sessions should be cleared. Because there is no way to automaticly check the files every x hours the session files are checked on certain requests.
This setting is the chance this check will happen. In this case 2 out of 100 for every request.

I think the only session driver that currently needs this is the database driver.

If you sweep the storage when it is full, there is a chance that new sessions won't be able to start untill the storage has been sweeped.
If you would sweep the storage on every request, all of your requests would become very slow.

0
votes

I totally agree with the answer from Jerodev.

For anyone looking for this right now, as of Laravel 8, here are the methods from:

\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php:

/**
 * Remove the garbage from the session if necessary.
 *
 * @param  \Illuminate\Contracts\Session\Session  $session
 * @return void
 */
protected function collectGarbage(Session $session)
{
    $config = $this->manager->getSessionConfig();

    // Here we will see if this request hits the garbage collection lottery by hitting
    // the odds needed to perform garbage collection on any given request. If we do
    // hit it, we'll call this handler to let it delete all the expired sessions.
    if ($this->configHitsLottery($config)) {
        $session->getHandler()->gc($this->getSessionLifetimeInSeconds());
    }
}

/**
 * Determine if the configuration odds hit the lottery.
 *
 * @param  array  $config
 * @return bool
 */
protected function configHitsLottery(array $config)
{
    return random_int(1, $config['lottery'][1]) <= $config['lottery'][0];
}

The default value is in config/session.php is [2, 100].

So configHitsLottery() would calculate a random integer between 1 and 100 and will compare it to 2, like this:

return random_int(1, 100) <= 2;