Thread safety and active_record_store sessions


#1

Hello,

I’m having problems using config.threadsafe! and sessions. On the page
two flash charts are initialized, both request data from the server
using a different action (eg chart_part1 and chart_part2). In both of
the actions I need to get and set values from the session, however the
session does not seem to be thread safe.

A small testcase like:

def index
session[:foo] = 0
logger.info("[SESSION] #{session[:foo]}")
end

def concurrent_action_chart_part1
session[:foo] += 1
logger.info("[SESSION] #{session[:foo]}")
end

def concurrent_action_chart_part2
session[:foo] += 1
logger.info("[SESSION] #{session[:foo]}")
end

def last_action_non_concurrent
session[:foo] += 1
logger.info("[SESSION] #{session[:foo]}")
end

Gives an output of:
[SESSION] 0
[SESSION] 1
[SESSION] 1
[SESSION] 2

Where I hoped it to be 0-1-2-3 :).

Is it possible to set some kind of mutex on the session?

Regards Andres


A. Koetsier M.Sc., Andrès
Oblivion B.V.

telefoon: +31 55 32 32 537
e-mail: removed_email_address@domain.invalid_ mailto:removed_email_address@domain.invalid
web: www.oblivion.nl http://www.oblivion.nl/


#2

Andres K. wrote:

Hello,

I’m having problems using config.threadsafe! and sessions. On the page
two flash charts are initialized, both request data from the server
using a different action (eg chart_part1 and chart_part2). In both of
the actions I need to get and set values from the session, however the
session does not seem to be thread safe.

Gives an output of:
[SESSION] 0
[SESSION] 1
[SESSION] 1
[SESSION] 2

Where I hoped it to be 0-1-2-3 :).

Is it possible to set some kind of mutex on the session?

This is not unexpected. What happens is that you have two requests come
in at the same time, both getting a copy of the session, both updating
it, and both putting it back. Since they both see the same value when
they start, they put the same value back.

This isn’t really a matter of thread safety, since doing the same thing
with multiple Rails instances wouldn’t work either without some kind of
shared lock. If there were two instances or two processes, they could
both easily end up doing the same thing.

What you probably want here is either something transactional (like the
database, or perhaps a transactional cache?) or if you can guarantee
only one process, one Rails instance, then yes; you could have requests
hold a global mutex when doing these shared operations. To me, the
transactional approach sounds better; let someone who’s already written
transaction logic do the work for you.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email