Search code examples
ruby-on-railsrubysessionunicorn

How is rails session shared among unicorn workers?


I am using unicorn as rails server, I have configured five workers for it.

I was not sure if this would affect user session, so I did a little experiment:

puts "------"
puts session[:session_id]
puts "session obj: #{session.hash}"
puts "pid: #{Process.pid}"

This is the result

------
69db720b6620288416ae4ba6f921dfb8
session obj: -4054823339922854099
pid: 4396
------
69db720b6620288416ae4ba6f921dfb8
session obj: 4220002746750993661
pid: 4527
------
69db720b6620288416ae4ba6f921dfb8
session obj: 2637320844486598221
pid: 4396

The session id is always the same

The session object is different every time

The pids for the first and third requests are the same

So I assume that rails session content(not singleton object, which can not be since each worker has its own process) is shared between different unicorn workers under the same master, but is this documented anywhere?

And is it implemented by the rails framework? or is unicorn_rails doing this?


Solution

  • This partly depends on the session store used. The default is the cookie store where the entire data is serialized and stored inside the session cookie. Other stores just store an id in the session cookie and fetch the data from some other source (eg redis)

    While session looks like an instance of Hash it's not - it's an instance of Request::Session which contains a bunch of other things (such as the details of the current request) so it's normal for session.hash to be different each time.

    You can turn the session into an actual hash with session.to_hash, although even then you will probably find that session.to_hash.hash differs across processes since hash values are not guaranteed to be the same across processes (in particular, for strings they are process dependant)