Updating the sessions table

Hi everyone,

I've got a problem that has me stumped.

I've got an application running rails 2.3.8, ruby 1.8.7. I'm using
the Activerecord Session store with MySQL.

On my development site, the session table's updated_at column has its
timestamp updated on every request. On my production site the
behavior is very erratic. Some sessions update some of the time,
others never change from the created_at time, and there's no apparent
link behind who gets updated and who doesn't.

I've been tearing my hair out with this, and I'm not finding anything
with Google.

Is there something inherently different about how sessions are handled
in production vs. development? Can anyone suggest a place to start
looking? I'm lost because it's working perfectly on my development
machine. I'm wondering if it's a traffic based thing - since my
development machine has generally less than 5 or 6 users on it at a
time, while the production site can have hundreds of users active at
any given moment. Other than that, I'm at a loss. Any ideas?

Thanks so much,
Andrew

You have a very interesting problem!

Hi everyone,

I've got a problem that has me stumped.

I've got an application running rails 2.3.8, ruby 1.8.7. I'm using
the Activerecord Session store with MySQL.

To confirm, this is the setup for both production and development systems?

On my development site, the session table's updated_at column has its
timestamp updated on every request. On my production site the
behavior is very erratic. Some sessions update some of the time,
others never change from the created_at time, and there's no apparent
link behind who gets updated and who doesn't.

How are you testing this? From where do you derive your assertions?

I've been tearing my hair out with this, and I'm not finding anything
with Google.

Is there something inherently different about how sessions are handled
in production vs. development? Can anyone suggest a place to start
looking?

What sort of logging are you doing? If you had logs of user activity
and session timestamps that might help shake out some clues.

I'm lost because it's working perfectly on my development
machine. I'm wondering if it's a traffic based thing - since my
development machine has generally less than 5 or 6 users on it at a
time, while the production site can have hundreds of users active at
any given moment.

Are your users reporting any peculiar behavior in your app? Have you
verified that your app is _not_ producing the proper SQL to update the
session timestamps?

You have a very interesting problem!

Thanks... I think...

You have a very interesting problem!

Thanks... I think...

> Hi everyone,

> I've got a problem that has me stumped.

> I've got an application running rails 2.3.8, ruby 1.8.7. I'm using
> the Activerecord Session store with MySQL.

To confirm, this is the setup for both production and development systems?

# rails -v
Rails 2.3.8
# ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [amd64-freebsd7]
#

Identical on both systems. Both the development and production
systems use the same database server. In case it matters, it is
running mysql Ver 14.14 Distrib 5.1.39, for portbld-freebsd7.2
(amd64) using 5.2

> On my development site, the session table's updated_at column has its
> timestamp updated on every request. On my production site the
> behavior is very erratic. Some sessions update some of the time,
> others never change from the created_at time, and there's no apparent
> link behind who gets updated and who doesn't.

How are you testing this? From where do you derive your assertions?

At the moment I am reduced to testing this by observing the database
tables. Admittedly, I don't know for a fact that it never fails on
the development side, as it receives exponentially lower traffic
levels.

I've run siege on both the development and production sites,
simulating 30 users. Siege keeps and respects cookies, so I end up
with exactly 30 new sessions. While I leave the test running, I run a
query on the MySQL server to watch the updated_at column. On the
development machine the timestamps are consistently changing. Do I
know for a fact that each request is resulting in a refresh, no...
Siege adds a randomizes which cookie makes the request, and adds
random delays between each request, so it's possible that some are
getting missed, but it appears to me to be pretty good.

When I run the exact same test on my production box, and I observe the
sessions table, the updated_at is changed only very sporadically.
There's no rhyme or reason to when it gets updated. Siege is
requesting the same URL each time (the site homepage), so it shouldn't
be a variation between code for different models/controllers.

> I've been tearing my hair out with this, and I'm not finding anything
> with Google.

> Is there something inherently different about how sessions are handled
> in production vs. development? Can anyone suggest a place to start
> looking?

What sort of logging are you doing? If you had logs of user activity
and session timestamps that might help shake out some clues.

I'm running the default logging level in both development and
production. If you think more detailed logging in production would be
interesting I can turn it on.

> I'm lost because it's working perfectly on my development
> machine. I'm wondering if it's a traffic based thing - since my
> development machine has generally less than 5 or 6 users on it at a
> time, while the production site can have hundreds of users active at
> any given moment.

Are your users reporting any peculiar behavior in your app? Have you
verified that your app is _not_ producing the proper SQL to update the
session timestamps?

My users are reporting that they are quite pissed, because I clear the
session table every 20 minutes to clear stale sessions, as I count
"online users" via the session table. I run a sql query that deletes
sessions that have an updated_at timestamp < 20 minutes. Of course,
if the user's session isn't getting updated then they get "cleaned up"
and they have to log back in because their session is gone.

> Other than that, I'm at a loss. Any ideas?

For the heck of it, I added a specific write to the session in the
application controller. I added:

session[:foobar] = Time.now

to the application controller. It seems to have worked... with that
code in sessions update consistently.

Stupid question, if nothing is explicitly written to the session hash
in app code does rails update the session table anyway? In other
words, does the session hash change without me explicitly changing
something in it? Or does rails write to the session table on every
request regardless of if something changes in the session hash?

Rails > 2.3 sessions are Rack sessions are lazy. Which is to say, if
you don't read a value from the session it is never loaded up; if you
don't write a value to the session it is never updated.

Still doesn't explain why they are updating every request in
development. I _don't_ write a lot of data to the session, so I could
understand why they wouldn't update at all, but they are.

Unless... I'm wondering if I _do_ write something if a user isn't
logged in... which would be the case with my siege tests. Off to do a
little more testing.

Is there a more preferable way to track who is online and active, or a
way to make the sessions to be "unlazy", or is writing a dummy value
into the cookie every time an acceptable workaround?

Thanks for your continued follow up on this!

Still doesn't explain why they are updating every request in
development. I _don't_ write a lot of data to the session, so I could
understand why they wouldn't update at all, but they are.

Do you write data to the session on every request? If so, they'll update.

Unless... I'm wondering if I _do_ write something if a user isn't
logged in... which would be the case with my siege tests. Off to do a
little more testing.

Let me know how that goes?

Is there a more preferable way to track who is online and active, or a
way to make the sessions to be "unlazy", or is writing a dummy value
into the cookie every time an acceptable workaround?

Is it acceptable to you?

Thanks for your continued follow up on this!

Sure, no problem.