Best Way to Cache a Response in Sinatra

Best way to cache a response in Sinatra?

Personally, I prefer to use redis for this type of things over memcached. I have an app that I use redis in pretty extensively, using it in a similar way to what you described. If I make a call that is not cached, page load time is upwards of 5 seconds, with redis, the load time drops to around 0.3 seconds. You can set an expires time as well, which can be changed quite easily. I would do something like this to retrieve the data from the cache.

require 'redis'
get '/my_data/:id' do
redis = Redis.new
if redis[params[:id]]
send_file redis[params[:id]], :type => 'application/json'
end
end

Then when you wanted to save the data to the cache, perhaps something like this:

require 'redis'
redis = Redis.new
<make API calls here and build your JSON>
redis[id] = json
redis.expire(id, 3600*24*5)

Sinatra - Setting Cache-Control Headers via config.ru

Here's how to set long expiry headers for static assets, and an arbitrary expiry header for you main content on Heroku:

gemfile:

gem 'rack-contrib'

config.ru:

require 'rack/contrib'

get '*.html' do |page|
# whatever code you need to serve up your main pages
# goes here... use Rack::File I guess.
page
end

# Set content headers for that content...
before do
expires 5001, :public, :must_revalidate
end

# Assets in /static/stylesheets (domain.com/stylesheets)
# are served by Rack StaticCache, with a default 2 year expiry.

use Rack::StaticCache, :urls => ["/stylesheets"], :root => Dir.pwd + '/static'

run Sinatra::Application

By default that will give you a 2 year expiry for content listed in the array of urls (static/stylesheets, static/images etc.).

You have to move from /public to /static because otherwise you are unnecessarily fighting with Heroku's nginx config (the right place to apply these sorts of settings really...).

I know you said you're trying to not use Rack Contrib but that makes no sense. There's no harm in using a tiny 90 line library to do this https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/static_cache.rb.

The "right" way would be to host static content on an environment where you can configure nginx, and the second best way is renaming your static file path so heroku ignores it, and use rack static to serve static files with the headers you want.

--

Also to be clear, simply renaming your public folder to something else will allow you to do this via routes, and the normal Sinatra expires function. But I'd use StaticCache because it's less verbose. (The real issue is Heroku doesn't let nginx talk to your app for requests to public/, I believe.)

How to set HTTP response (cache) headers in a Sinatra app hosted on Heroku

Apart from the fact that I wouldn't get through the Sinatra stack just to serve static files, you'd call

cache_control :public, max_age: 60

to cache for a minute. cache_control is a helper that comes with Sinatra.

Otherwise, I'd suggest you have a look at http://www.sinatrarb.com/configuration.html to see how Sinatra is set up so you don't have do deal with serving static files.

Hope this helps.

edit: I just saw you were explicitly asking for the Expires header. I'm not sure, but that should be fairly the same way as Cache-Control. Sorry for the confusion

Caching a redirect to a static image in Sinatra

You set the Cache-Control on a per route basis:

get '/stream/:service/:stream_id.png' do
# Building image_url omitted
response['Cache-Control'] = "public, max-age=0, must-revalidate"
redirect image_url
end

Sinatra app with unicorn and memcached should return 304 codes for cache hits?

Unicorn cannot know how your application handles caching. Therefore it cannot set etags for you.

Like Rajesh said, 304 is about browser cache.
You will have to generate an Etag hash in your app and then send it to the browser (via header).

According to this post browsers have support for etags : Browser support for eTags etags.

Here is the official doc on 304 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5

Edit :
Take a look here to implement it with sinatra :

http://www.sinatrarb.com/intro#Cache%20Control

http://opensoul.org/blog/archives/2011/01/29/etags-with-memcached/

How can I control caching for static assets when using Sinatra?

You can use the static_cache_control setting to set the Cache-Control header for static files served by Sinatra:

set :static_cache_control, [:public, max_age: 60 * 60 * 24 * 365]

Note you need to use an explicit array [...].

Also this will apply to all files in the public directory, i.e. you can’t specify different headers for css and javascript files.

(If you’re not using Heroku and are using Apache or Nginx to serve static files then this won’t work, in that case you’d need to configure your webserver separately).

Sinatra cache control is not working

Which file you add max-age header?

If it's JavaScript or CSS file, please try to build files with Sinatra-assetpack.

Files built are located in under 'public' directory.

Please see the following, written how to build.

http://ricostacruz.com/sinatra-assetpack/#need_to_build_the_files

sinatra-cors not responding with 200 when using middleware

The issue was related to an error in my middleware (Error module was not included in the source, and the default configuration of Rack caused errors not to be displayed)



Related Topics



Leave a reply



Submit