Reputation: 365
Ruby on Rails 4.1.4
I made an interface to a Twitch gem, to fetch information of the current stream, mainly whether it is online or not, but also stuff like the current title and game being played.
Since the website has a lot of traffic, I can't make a request every time a user walks in, so instead I need to cache this information.
Cached information is stored as a class variable @@stream_data inside class: Twitcher.
I've made a rake task to update this using cronjobs, calling Twitcher.refresh_stream, but naturally that is not running within my active process (to which every visitor is connecting to) but instead a separate process. So the @@stream_data on the actual app is always empty.
Is there a way to run code, within my currently running rails app, every X minutes? Or a better approach, for that matter.
Thank you for your time!
Upvotes: 0
Views: 1477
Reputation: 84114
This sounds like a good call for caching
Rails.cache.fetch("stream_data", expires_in: 5.minutes) do
fetch_new_data
end
If the data is in the cache and is not old then it will be returned without executing the block, if not the block is used to populate the cache.
The default cache store just keeps things in memory so doesn't fix your problem: you'll need to pick a cache store that is shared across your processes. Both redis and memcached (via the dalli gem) are popular choices.
Upvotes: 1
Reputation: 43
I actually had a similar problem with using google analytics. Google analytics requires that you have an API key for each request. However the api key would expire every hour. If you requested a new api key for every google analytics request, it'd be very slow per request.
So what I did was make another class variable @@expires_at
. Now in every method that made a request to google analytics, I would check @@expires_at.past?
. If it was true, then I would refresh the api key and set @@expires_at = 45.minutes.from_now
.
You can do something like this.
def method_that_needs_stream_data
renew_data if @@expires_at.past?
# use @@stream_data
end
def renew_data
# renew @@stream_data here
@@expires_at = 5.minutes.from_now
end
Tell me how it goes.
Upvotes: 0