Search code examples
rubycachingdatasetsinatrasequel

Caching dataset results in Sequel and Sinatra


I'm building an API with Sinatra along with Sequel as ORM on a postgres database.

I have some complexes datasets to query in a paging style, so i'd like to keep the dataset in cache for following next pages requests after a first call.

I've read Sequel dataset are cached by default, but i need to keep this object between 2 requests to benefit this behavior. So I was wondering to put this object somewhere to retrieve it later if the same query is called again rather than doing a full new dataset each time.

I tried in Sinatra session hash, but i've got a TypeError : can't dump anonymous class #<Class:0x000000028c13b8> when putting the object dataset in it.

I'm wondering maybe to use memcached for that.

Any advices on the best way to do that will be very appreciated, thanks.


Solution

  • Memcached or Redis (using LRU) would likely be appropriate solutions for what you are describing. The Ruby Dalli gem makes it pretty easy to get started with memcached. You can find it at https://github.com/mperham/dalli.

    On the Github page you will see the following basic example

    require 'dalli'
    options = { :namespace => "app_v1", :compress => true }
    dc = Dalli::Client.new('localhost:11211', options)
    dc.set('abc', 123)
    value = dc.get('abc')
    

    This illustrates the basics to use the gem. Consider that Memcached is simply a key/value store utilizing LRU (least recently used) fallout. This means you allocate memory to Memcached and let your keys organically expire unless there is a reason to manually expire the key.

    From there it becomes simply attempting to fetch a key from memcached, and then only running your real queries if there is no match found.

    found = dc.get('my_unique_key')
    unless found
      # Do your Sequel query here
      dc.set('my_unique_key', 'value_goes_here')
    end