Welcome Guest, Not a member yet? Register   Sign In
Session: Error while trying to free lock for ci_session
#5

(03-06-2017, 03:14 AM)Narf Wrote: Both ... but more of the latter.

"Render" is the wrong term to use (that happens client side). However, by default, the lock is released after the entire script execution completes, which includes completely flushing the output, and that does depend on connection speeds.
You can get work around that by calling session_write_close() as soon as you no longer need to access session data.

But that being said, even mobile connections are quite speedy nowadays, so most of the time it is inefficient server-side processing that's causing problems.

Thanks, Narf. That at least gives me a definitive place to start. I've placed this at the bottom of index.php:
PHP Code:
// Log slow script execution times
$scriptExeTime microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
if (
$scriptExeTime 5.0) {
 
log_message('ERROR'"{$scriptExeTime} " current_url());


Unfortunately, I'm still getting the "Error while trying to free lock" error but without this log message to accompany it. Is the bottom of index.php the best place to put this log or is there a better way to do this? I've also added current_url() and stack trace when logging the "free lock" error but the urls aren't consistent (it can be anywhere). I have both NewRelic and Blackfire to help me profile the application but I can't seem to catch the specific issue through them either.

In regards to session_write_close(), I forgot to mention that I've had a MY_Session.php override with this constructor:

PHP Code:
public function __construct(array $params = array())
{
 
   $CI =& get_instance();
 
   $ciController $CI->uri->segment(10);
 
   $ciFunction $CI->uri->segment(20);

 
   $driver config_item('sess_driver');
 
   if ($driver === 'redis') {
 
       $CI =& get_instance();
 
       $this->_setup_redis($CI);
 
       if ( ! $this->isConnected) {
 
           return NULL;
 
       }

 
       // Don't call session start if a user is not logged in unless
 
       // they are in the login or registration sections.
 
       if ($ciController === 'login' && $ciFunction === 'check') {
 
           // Ignore login check
 
       } elseif ($ciController === 'register') {
 
           // Ignore registration
 
       } else {
 
           $cookieName $CI->config->item('sess_cookie_name');
 
           if (empty($_COOKIE[$cookieName])) {
 
               // Not logged in since no session cookie
 
               return NULL;
 
           }

 
           $session $this->redis->get("ci_session:{$_COOKIE[$cookieName]}");
 
           if (empty($session) || strpos($session'username') === FALSE) {
 
               // Session ID found in cookie but no active session found
 
               // so skip trying to start a session.
 
               return NULL;
 
           }
 
       }
 
   }
 
   parent::__construct($params);

 
   // Release session locks early to reduce locking errors
 
   // but not for sections that set session data.
 
   if ($ciController !== 'login' &&
 
       $ciController !== 'register' &&
 
       $ciController !== 'account') {
 
       session_write_close();
 
   }


The top part prevents session_start() from being called when a user isn't logged in and the bottom (should) always calls session_write_close() right after session_start() is called in the parent constructor. Is this the most efficient place to call session_write_close()? I've also always been uncomfortable modifying core functions so are there any glaring issues with the above code as well?
Reply


Messages In This Thread
RE: Session: Error while trying to free lock for ci_session - by Nichiren - 03-06-2017, 11:13 AM



Theme © iAndrew 2016 - Forum software by © MyBB