Skip to content

Instantly share code, notes, and snippets.

@franvarney
Last active April 3, 2018 18:13
Show Gist options
  • Save franvarney/d22c00c554c200403c83798ebdd90506 to your computer and use it in GitHub Desktop.
Save franvarney/d22c00c554c200403c83798ebdd90506 to your computer and use it in GitHub Desktop.

Question

Design a generic caching system for vehicle data that minimizes the number of requests that SC must make to a given vehicle.

Vehicle data response format
{
  "odometer": {
    "distance": 104400.50
  },
  "location": {
    "latitude": 1234,
    "longitude": 1234
  }
}
  • Each key in the data object has a one-to-one mapping with an endpoint on SC's API
    • Ex: odometer -> GET /odometer

Notes

Cache has:
  • Freshness
  • Validation
  • Invalidation
Cache can be:
  • Server side - avoids more database operations
  • Client side - avoids more network requests
  • Stored in multiple types of data stores like Redis, Memcached, or just in memory

Design

Cache Methods

  • config(obj)
    • Set up a database connection string here
    • Default settings like expiration time
  • set(key, data, expirationTimestamp)
    • Adds data to data store by key
    • Set an expiration timestamp
  • get(key)
    • Checks if data by key exists in cache. If not, continues on with the request to get new data
    • Checks if the data is expired. If it is, continues on with the request to get fresh data
  • remove(key)
    • Removes data by some key if it exists
General Functionality
  • Retrieve a resource
    • Resource exists in cache and is not expired, uses get to return cached resource.
    • Resource exists in cache and is expired, gets fresh data, caches through set and returns resource.
    • Resource does not exist, gets fresh data, caches through set and returns resource.
  • Create or update a resource.
    • Invalidates current data by using set to add fresh data to the cache.
  • Delete a resource
    • Invalidates current data by using remove to delete the data from the cache.

Concerning individual keys like odometer and location, there are a few different solutions.

  1. If the vehicle id is the key and assuming it is somehow available during requests to child resources like /odometer, then the whole vehicle object would be added and modified (get existing/new object>merge sub resource into parent resource>set). Invalidation issues would be obvious.
  2. The data in vehicle data response could be broken down and stored something like { vehicle_id_odometer: odometerObj } so when subsequent requests are made to the child resource, only that data is add or modified. Less invalidation issues overall since only specific parts would be added and modified as needed. Expiration times could be set shorter for properties like odometer that are updated frequently.
  3. Only the whole vehicle data object is stored. Child resources would be plucked from the larger object and returned separately, assuming the vehicle id is available. But the whole data object has to be reset if only child resources are modified.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment