Reputation: 1911
I have an application with user 'Notifications' think SO or facebook or twitter. However, as notifications won't necessarily change on every page view I decided to save them in memcached.
def get_notification
if current_user
mc = Dalli::Client.new('localhost:11211')
require_dependency 'notification.rb'
@new_notification = mc.get(current_user.id.to_s+'new_notification')
if @new_notification == nil
@new_notification = Notification.getNew(current_user.id)
mc.set(current_user.id.to_s+'notification',@new_notification)
end
end
end
I overlooked the obvious flaw in this implementation. Once the notifications are loaded they would never be refreshed until the user logs out or the cache entry expires. One way to do this is to negate the user's cache entry when a event for a new notification occurs. This would force a new request to the db. Is there any other way to implement this?
Upvotes: 0
Views: 661
Reputation: 34155
First using Cache Stores
option you can instruct rails to use Memchached
config.cache_store = :mem_cache_store, "example.com"
This cache store uses memcached server to provide a centralized cache for your application. Rails uses the bundled dalli gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very a high performance and redundancy.
When initializing the cache, you need to specify the addresses for all memcached servers in your cluster. If none is specified, it will assume memcached is running on the local host on the default port, but this is not an ideal set up for larger sites.
The write and fetch methods on this cache accept two additional options that take advantage of features specific to memcached. You can specify :raw to send a value directly to the server with no serialization. The value must be a string or number. You can use memcached direct operation like increment and decrement only on raw values. You can also specify :unless_exist if you don't want memcached to overwrite an existing entry.
Using rails Cache store instead of directly using Dalli allows you to use the following Nicer API
Rails.cache.read('key')
Rails.cache.write('key', value)
Rails.cache.fetch('key') { value }
Now, rails for actually caching. you can use Declarative Etags
or Fragment Caching
to cache the notifications. here is an example using Declarative Etags
def get_notification
if current_user
@new_notification = Notification.getNew(current_user.id)
end
refresh_when @new_notification
end
Now the way declarative E-tags works is Template is not rendered when request
sends a matching ETag & cache copy is sent. However, when @new_notification
changes the E-tag value will change too. Thus causing the cache to expire. Now, Caching is a vast topic to cover & there are variously techniques to do it. so probally I won't give you a full answers but I would point to the following resources so you can learn more:
Happy Caching ;-)
Upvotes: 1