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.