Created
November 3, 2016 20:53
-
-
Save oinak/61ef55fdf5ebc4e5a881e78cab18877a to your computer and use it in GitHub Desktop.
A meditation on service caches, with an example stroage class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'securerandom' | |
| class JsonFileCache | |
| def initialize(path = nil) | |
| @path = path || "/tmp/cache/#{SecureRandom.uuid}" # safe default | |
| end | |
| # Retrieves whole cache or single record if key is provided | |
| def get(key = nil) | |
| @cache ||= load_file | |
| key ? @cache[key] : @cache | |
| end | |
| # Sets or resets a key valua and writes to storage | |
| def set(key, data) | |
| @cache[key] = data | |
| write | |
| data | |
| end | |
| private | |
| def write | |
| File.write(@path, JSON.dump(@cache)) | |
| end | |
| def load_file | |
| JSON.parse(File.read(@path)) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Examples: | |
| # cache = JsonFileCache.new("tmp/cache/geolocation.json") | |
| # $geolocation = ServiceCache.new(GeolocalateUser, cache) | |
| # | |
| # ll = $geolocation.get(User.last) | |
| # => { lat: 3.0, lng: 40.1 } # calling API | |
| # | |
| # ll = $geolocation.get(User.last) | |
| # => { lat: 3.0, lng: 40.1 } # reading file | |
| # | |
| # Requirements: | |
| # object: must respond to 'id' | |
| # service: must respond to 'call' with one argument | |
| # cache: must respond to get(key) and set(key, response) | |
| # cache.set() must be complatible with service.call response type | |
| class ServiceCache | |
| def initialize(service:, cache:) | |
| @service = service | |
| @cache = cache | |
| end | |
| def get(object) | |
| cache_read(object) || service_call(object) | |
| end | |
| private | |
| def cache_read(object) | |
| @cache.get(object.id) | |
| end | |
| def service_call(object) | |
| response = @service.call(object) | |
| @cache.set(object.id, response) # set() returns 'response' | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment