Description
I was developing a Rails app that switches the session store to redis and accidentally set expire_after: nil
. I found a strange behavior with that setting and I'd like to report it.
- redis-rack stores session keys in cookies and session values in redis.
expire_after: nil
setting makes lifetime mismatch- Session key is saved as "session cookie" (expires when browser session ends)
- Session value is saved in redis without ttl
With expire_after: nil
setting, client's session key is sometime expired, but session value is not expired.
So the redis will accumulate more and more non-volatile keys.
Of course, I am aware that using the redis session store with expire_after: nil
is not a good idea. However, the current behavior is confused for me.
Reproduction
I checked with the following code.
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "sinatra", "2.2.0"
gem "webrick", "1.7.0"
gem "redis-rack", "2.1.4"
end
require "sinatra/base"
require "redis-rack"
enable :sessions
set :session_store, Rack::Session::Redis, expire_after: nil
get "/" do
session[:data] = "hello"
end
Sinatra::Application.run!
Procedure
- Launch above application with
ruby app.rb
- Access by browser
What to do
How the expire_after: nil
setting should work.
1. Match the session key deadline
- Session key is stored in session cookie
- Session values as volatile as session keys
- However, the timing of session cookie expiration is unknown, so set an appropriate default expiration date?
Storing session with expire_after: nil
in the session cookie setting is rack's default behavior.
This method seems the least confusing.
2. Match the session value expiration date
- Session key is stored in non-volatile cookie
- Session values stored as redis without ttl
There may be some confusion because the default session behavior of rack.
However, it may be consistent within redis-rack.
3. Nothing to do
As I described earlier, I think it is a confusing and not happy behavior.