1

I have a web app which uses Laravel 4.2 with the session file driver. It runs over a https protocol and all users are stored in one database. We get a lot of reports that users are being randomly logged out, but I can't reproduce the issue in our dev environment. I suspect the garbage collector, could it be cleaning out the wrong session files or something? Should we switch to database session storage?

Here's some of our session config:

'lifetime' => 720,
'expire_on_close' => false,
'lottery' => array(2, 100), 

Our php.ini has the gc_maxlifetime set to 43200.

As far as I know the server runs debian 7 with no load balancer or extra session managers installed or configured. Whatever comes with debian 7 is what is used.

Thankful for any help!

Mattias
  • 1,111
  • 1
  • 14
  • 23
  • Can you edit the question with some more details about your environment? Single server or multiple with load balancers and if so do you have a session state manager? – BMac Apr 13 '15 at 08:30
  • Thanks, added this: As far as I know the server runs debian 7 with no load balancer or extra session managers installed or configured. Whatever comes with debian 7 is what is used. – Mattias Apr 13 '15 at 08:36
  • ok, Are you running on a shared environment? – BMac Apr 13 '15 at 08:38
  • I'm no expert on the server environment but I know we use a virtual private server, so I'm guessing that's a no. – Mattias Apr 13 '15 at 08:39

1 Answers1

1

No your problem is elsewhere, the lottery is not for selecting sessions to randomly delete, it is to pick random requests to delete EXPIRED sessions and expired sessions only.

In an ideal world you would want in certain acceptable intervals the system to delete all expired sessions but the Laravel developers have decided many will not actually set up the php artisan schedule:run to their CRON Jobs or Scheduled Tasks on the operating system.

So instead of taking every user page requests to run a SQL query to

DELETE FROM sessions WHERE lastactivity < [session_time]

The default 2 in a 100 lottery makes sure this happens during random HTTP requests at the expense of some unluck visitor for price of an average of a tenth miliecond.

You can see in the StartSession middleware where it cleans up the sessions using the method collectGarbage which cleanrs the session based on the lottery config (above).

https://github.com/illuminate/session/blob/master/Middleware/StartSession.php

The default configurations are [2, 100]. It means that a random integer is chosen between 1 and 100, if it's lower or equals to 2 the cache will be cleared. (Aka you the visitor have a 2% possibility to clear the cache every call).

You can enhance this if you think this is what is happening to it becoming a php artisan command that you place in the Kernel.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Session; //for sake of simplicity I am assuming this exists

class PruneExpiredSessions extends Command
{
    
    protected $signature = 'sessions:prune';

    protected $description = 'Override default DB Session garbage collection';

    public function handle()
    {

        Session::where('last_activity',< time()-(60*60*48))->delete();
        $this->info('Successfully deleted Expired Sessions' );
        return Command::SUCCESS;
    }
}

Now simply in app/console/kernel.php

<?php

namespace App\Console; 

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')->hourly();
        $schedule->command('telescope:prune --hours=48')->daily();
        $schedule->command('session:prune')->daily(); <--This is the line
    }
 ...
}

Just make sure to add php artisan schedule:run to your OS Scheduled Taks/Cron Job every minute

Neo
  • 11,078
  • 2
  • 68
  • 79