Lawnchair is a project mainly written in Ruby, based on the MIT license.
Speed up your app by caching expensive code in Redis or in the Ruby process itself
= Lawnchair
Fully featured caching mechanism for arbitrary pieces of resource expensive ruby code using Redis while being able to optionally store data in the Ruby process itself for maximum efficiency.
Lawnchair includes a Rails view helper that can be used to cache the rendered view code, but other than that everything should work fine in a Merb, Sinatra, or plain old Ruby app.
== Installation
sudo gem install lawnchair
== Usage Examples
All you really need to do is wrap some expensive piece of Ruby code in the Lawnchair.cache method as a block and it will be evaluated and the return value will cached in the given cache key.
MAKE SURE REDIS SERVER IS RUNNING PRIOR TO TRYING ANYTHING BELOW!!!
First, connect to the Redis database. This would most likely go into an environment.rb.
Lawnchair.connectdb
This will connect to a default database on localhost, if you want to connect to a particular database you can do:
Lawnchair.connectdb(Redis.new(:database => 11, :host => "127.0.0.1", :port => 6379))
Obligatory example:
Lawnchair.cache("cache_key2") do
(1..3).inject([]) do
|set, i| set << Time.now.strftime("%H:%M:%S")
sleep 1
set
end
end
The return value is exactly what you think it should be
["12:26:08", "12:26:09", "12:26:10"]
Now, since it is cached, any time this block method is called (for the next 60 minutes) it will return those values. also, you will note it comes back instantly, instead of waiting on those sleeps.
If an hour is too long, or short for the cache key expiration you can set that to anything you want using the :expires_in hash key and entering a time in seconds
Lawnchair.cache("cache_key", :expires_in => 1.day) do
end
Available options:
== Interpolating Data
Caching large pieces of the page can prove to be difficult in a highly dynamic environment. Content interpolation makes this easier to deal with common things such as user names, timestamps, flash messages and more.
cached_result = Lawnchair.cache("cached_time") { "current time: TIME" } => "current time: TIME"
Now let's interpolate this data with dynamic content.
cached_result = Lawnchair.cache("cached_time", :interpolate => {"TIME" => Time.now.to_s}) { "current time: TIME" } => "current time: Tue Aug 24 16:13:40 -0700 2010" cached_result = Lawnchair.cache("cached_time", :interpolate => {"TIME" => Time.now.to_s}) { "current time: TIME" } => "current time: Tue Aug 24 16:13:42 -0700 2010"
Notice that the timestamp is different for each call, even though the data is coming out of the cache.
== In Process Caching
If you want to get really fancy you can cache the values in process as well as in Redis. This can be a fairly significant win if you are running the Redis server on a different physical machine as all network latency is taken out of the equation, especially if you are hitting a cache key many times on the same request. Also, it's probably best not to store TONS of keys in there, as your ruby process can bloat fairly quickly if you put everything in there. Also, these will persist as long as the process is running, unless you manually expire it.
Lawnchair.cache("cache_key3", :in_process => true) do
end
This code will get cached in redis as well, so each different process that runs the expensive code in the block will get the value from redis, instead of having to run it to get the value.
== Accessing DataStores Directly
There are currently two different storage engines (Redis and InProcess) that you can use either together or independently, depending on your needs. If you want to just store something in process for example you can do
Lawnchair::StorageEngine::InProcess.fetch("cache_key4", :raw => true) do
end
Also, you can expire a key for a given storage engine directly by calling
Lawnchair::StorageEngine::InProcess.expire!("cache_key3") # For memory store or Lawnchair::StorageEngine::Redis.expire!("cache_key3") # For redis store
You can also access any of the methods for a given datastore directly, and choose to expire a key in whatever store you want.
Available methods are:
If you need to flush all the values in the Redis database
Lawnchair.flushdb
== Note on Patches/Pull Requests
== Copyright
Copyright (c) 2010 Shane Wolf. See LICENSE for details.
Thanks to Tyler Kovacs for the inspiration for content interpolation.