So, for one reason or another, I am using the built-in db store for sessions on the RidingResource site. I was about to embark on a path to utilizing sessions to help maintain the search selections across the site, and I noticed that the sessions database was full of… junk.
Rails is nice enough to provide us with a number of great built-in ways to handle sessions. Unfortunately, it is not nice enough to clean up after itself. I noticed that there is a built-in rake task (rake db:sessions:clear), but this actually just nukes the whole sessions table. Now, granted, I could run this as a cron at 4:00AM and it would probably not affect any users. But, I figured I should design a way to simply not affect any users regardless.
I found someone else who was trying to clean up session data and they figured out a MySQL query that works: DELETE FROM sessions WHERE updated_at < DATE_SUB(CURDATE(), INTERVAL 30 DAY); This will delete any sessions that haven’t been updated in 30 days. For our app, I decided that a 2-day interval is probably sufficient. The other cute benefit is that someone who comes back within two days will probably see their last search retained — that may or may not be desireable in the long run.
Since I had just written a rake task the other day to handle some stuff relating to paid advertisers and what not, I realized that I already had a tool that could (potentially) be used to process this MySQL query — rake. However, that required figuring out a way to run a MySQL query directly with rake.
Again, Rails to the rescue — it provides us with ActiveRecord::Base.connection.execute(sql). So, I created a rake task to do what was needed.
# clearing out sessions older than 2 days because we are using sessions to store # search information to maintain the search preferences in the show action desc "This task will delete sessions that have not been updated in 2 days." task :clean_sessions => :environment do ActiveRecord::Base.connection.execute("DELETE FROM sessions WHERE updated_at < DATE_SUB(CURDATE(), INTERVAL 2 DAY);") end
Combined with a cron job, this should work splendidly.