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
# 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