Skip to content

Instantly share code, notes, and snippets.

@micho
Created July 31, 2012 09:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micho/3215498 to your computer and use it in GitHub Desktop.
Save micho/3215498 to your computer and use it in GitHub Desktop.
Resource Cache mechanism, for projects and people
Resource Cache is a key-value auto-expiring cache, where we pass
the path for a base model + a resource owned by it + modifiers.
Structure
---------
Each cacheable entry is called with two or three parameters:
- Base Model: Typically a User or Project. Specifies who owns this
resource.
- Resource: A collection owned by the base model: tasks, people..
- Modifiers: Optional. Parameters for pagination, filtering, etc.
Examples
--------
User + "people": People in all my projects.
Project + "people": People for the specified project.
User + "tasks" + "mine": My tasks across all projects.
Project + "tasks": All tasks in a project.
Project + "tasks" + "user=123": All tasks for user 123 in a project.
Project + "tasks" + "count=20,page=2": Paginated tasks for project.
Expiration
----------
When the base model is modified caches are not expired.
When the resource is modified, we must manually update the timestamp
with a sweeper, so all the modified versions of it are expired.
When a new modifier is passed, the API call generates the view as
it would normally do and caches it.
We don't explicitly expire collections to free up memory, because
this would require a `read` for the updated_at key and a `del`.
Furthermore, this way we'd only be able to expire the unmodified
resource (base model + resource without modifiers), because
we have no way of finding modifiers for the resource.
Auto-expiration from the LRU cache cleans up values eventually.
Internals
---------
For each data piece, we store two separate values:
- The latest timestamp for the resource.
- The resource data, which depends on the timestamp and modifiers.
We expire resources (and all their modifiers) by updating the timestamp.
Multiple backend support
------------------------
Since all values are stored using a key-value format, we can swap
backends easily as long as they have a Rails.cache adapter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment