Update Session Lifetime

Hi,

I am using Phalcon\Session\Adapter\Redis as my Session Adapter with a lifetime of 3600. This works fine, but my Session always ends in an hour, even if there is activity on the site. How can i increase the lifetime on new activity? session->start() doesn't seem to do this.

This is how lifetime works. It's not gonna be updated on activity, just put 0 i guess.

edited Aug '16

Post your session service config (set in services container).

In general, lifetime represents maximum amount of time that the parent daemon/server will take into account before flushing object from memory/cache storage.

I always use\Phalcon\Session\Adapter\Libmemcached as a session storage adapter, and setting lifetime to 15 mins works fine since the underlying adapter will do refresh by default.

What you mean by refresh ? For me adapter never refreshes lifetime, and i am too for example after 1 hour session is cleared etc. I'm just using 0.

Post your session service config (set in services container).

In general, lifetime represents maximum amount of time that the parent daemon/server will take into account before flushing object from memory/cache storage.

I always use\Phalcon\Session\Adapter\Libmemcached as a session storage adapter, and setting lifetime to 15 mins works fine since the underlying adapter will do refresh by default.

edited Aug '16

Setting the lifetime to 0 means that the session only closes if the user does a logout. We all know that only a few users will do that.

So doing that means i will need to implement my own session recycling on top of the existing timeout that will run in background. I am not very keen on doing that. I also thought of extending the Redis Adapter with a function refresh() that is resetting the session keys with a new timeout. I think this will be the best and only solution.

@stamster You mean that if i would use Libmemcached it will automatically update the session lifetime after doing session->start()? So this behaviour is just missing in the redis adapter?

My Session config is the following:

return new RedisSession( [ 'uniqueId' => 'cdrsSession', 'host' => $config['redis']->host, 'port' => $config['redis']->port, 'persistent' => false, 'lifetime' => 3600, 'prefix' => 'session.', 'index' => 1, ] );

For all session adapter start method looks the same, so it won't update i think.

edited Aug '16

session service definition

 //create new session instance
    $daemon = new \Phalcon\Session\Adapter\Libmemcached(
        ['servers'  => [['host' => $config->_daemon->socket, 'port' => $config->_daemon->pipe, 'weight' => $config->_daemon->weight]],
        'client' => [
            Memcached::OPT_HASH => Memcached::HASH_MD5,
            Memcached::OPT_PREFIX_KEY => 'web.', //this is the KEY DOMAIN!
            Memcached::OPT_TCP_NODELAY => 1,
            Memcached::OPT_NO_BLOCK => 1,
            Memcached::OPT_CONNECT_TIMEOUT => 500
        ],
        'lifetime' => 900, //default lifetime of a session
        'prefix' => 'session_', //actual prefix of the keys
    ]);

//NOTE on lifetime: the actual value sent may either be Unix time (number of seconds since January 1, 1970, as an integer),
//or a number of seconds starting from current time.
//In the latter case, this number of seconds may not exceed 60*60*24*30 (number of seconds in 30 days);

    //Set session cookie name
    $daemon->setName('MySweetAppCookie');

    //Start session - Set Cookie HTTP header
    $daemon->start();

    //return session instance
    return $daemon;

ControllerBase

onConstruct() method implements this check:

  protected function isUserConnected() {
        return $this->session->has('userLoggedIn') ? true : false;
    }

Note: this shold not be necessary as the shared Session service should trigger this by default, if it doesn't, call to method has() will surely do the job.

End result if the user is active on the site, i.e. browsing pages etc. the has() method will contact Memcached daemon and update lifetime each time. This way, user will always have 15 min session lifetime before expiration. If he/she leaves the computer, session will expire.

I dont see any special "session refresh" handling in your code, so you say that your ->has call is updating the lifetime of your "userLoggedIn" session key?

edited Aug '16

@dstuecken There's no special refresh.

When I visit index page, session service will generate some ID -> cookie for me. My browser reads HTTP header Set-Cookie from response, where it finds session name value: puo16l0t5ha73llcfj0ju4qjs6ligu4t.

This is what is stored in Memcached daemon:

web.session_puo16l0t5ha73llcfj0ju4qjs6ligu4t

(remember that I set key domain and prefix in service definition).

On each web page load, my browser sends this key in a cookie field. The session service check internally whenever that key is still valid or not. So $daemon->start(); should trigger this (to call underlying session storage adapter). If the session expired due to innactivity (15 min out of office), the data for this key will become empty (the key will always be set!). So this will fail then: $this->session->has('userLoggedIn').

userLoggedIn is not set in a key with an ID puo16l0t5ha73llcfj0ju4qjs6ligu4t, which means user has been logged out.

@Jurigag: you should check libmemcached source, but what is sure - this approach works and has been proven.



112

Memcached behaves differently not because of the Phalcon Session Adapter but because memcached is different than Redis. By default Memcached is an LRU cache meaning no keys expire and data is only removed when the available memory is filled. Redis on the other hand is usually used with explicit TTLs. To make Redis behave like memcached you can either

  1. reset the TTL after read which would require extending the Phalcon Session Adapter
  2. configure your Redis instance to use an LRU expiration policy. I believe you'll also have to set an expire time long in the future because the Redis adapter, for me at least, doesn't like the value of 0.


112

Though it looks like the Redis adapter does automatically refresh for activity. I wasn't seeing the refresh because I was using Redis via the File adapter.



848

So, I have sanme problem. IS there any suggestion?