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

(This post was last modified: 05-26-2016, 10:33 AM by spjonez.)

(05-25-2016, 11:46 PM)Narf Wrote: Believe it or not, I've only ever looked at the manual and have never run redis.
But yes, phpredis is what it requires.

I'm seeing some really odd results in my logs, does this make any sense to you?

Code:
    public function write($session_id, $session_data)
    {
        if ( ! isset($this->_redis))
        {
            return $this->_fail();
        }
        // Was the ID regenerated?
        elseif ($session_id !== $this->_session_id)
        {
            if ( ! $this->_release_lock('1') OR ! $this->_get_lock($session_id))
            {
                return $this->_fail();
            }

            $this->_key_exists = FALSE;
            $this->_session_id = $session_id;
        }

        if (isset($this->_lock_key))
        {
            $this->_redis->setTimeout($this->_lock_key, 300);
            if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE)
            {
                if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration']))
                {
                    $this->_fingerprint = $fingerprint;
                    $this->_key_exists = TRUE;
                    return $this->_success;
                }

                return $this->_fail();
            }

            return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']))
                ? $this->_success
                : $this->_fail();
        }

        return $this->_fail();
    }

Only change is to add '1' to _release_lock.

Code:
    public function close()
    {
        if (isset($this->_redis))
        {
            try {
                if ($this->_redis->ping() === '+PONG')
                {
                    $this->_release_lock('2');
                    if ($this->_redis->close() === $this->_failure)
                    {
                        return $this->_fail();
                    }
                }
            }
            catch (RedisException $e)
            {
                log_message('error', 'Session: Got RedisException on close(): '.$e->getMessage());
            }

            $this->_redis = NULL;
            return $this->_success;
        }

        return $this->_success;
    }

Only change is to add '2' to _release_lock.

Code:
    protected function _release_lock($code = 0)
    {
        if (isset($this->_redis, $this->_lock_key) && $this->_lock)
        {
            $exists = $this->_redis->exists($this->_lock_key);
            $del = $this->_redis->delete($this->_lock_key);

            if ( !$del)
            {
                $exists2 = $this->_redis->exists($this->_lock_key);

                log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key . ', code=' . $code . ', del=' . var_export($del,true) . ', exists=' . var_export($exists,true) . ', exists2=' . var_export($exists2,true));
                return FALSE;
            }

            $this->_lock_key = NULL;
            $this->_lock = FALSE;
        }

        return TRUE;
    }

Added exists calls before and after the delete and to print to the delete call's response and $code being passed. This is the message it produces:

Session: Error while trying to free lock for ci_session:7ed553ebbca1ba962394dcc3a0c934e85b1c25c3:lock, code=2, del=0, exists=true, exists2=false

The key exists before the delete call, the delete call returns 0, yet the key is in fact deleted as shown by the second exists call? The only way I've been able to reproduce this semi reliably is to trigger 2 or more concurrent AJAX requests.

According to the Redis documentation delete should return a long if successful or 0 if it fails. Is this also true for keys set to expire? I've never used those before to know what the expected behaviour is in this situation.
Reply


Messages In This Thread
RE: Session: Error while trying to free lock for ci_session - by spjonez - 05-26-2016, 10:13 AM



Theme © iAndrew 2016 - Forum software by © MyBB