geo_code_repo.rb

 1# frozen_string_literal: true
 2
 3require "cbor"
 4require "json"
 5
 6require_relative "geo_code"
 7
 8class GeoCodeRepo
 9	def initialize(memcache: MEMCACHE)
10		@memcache = memcache
11	end
12
13	def find(q)
14		cache(q) {
15			EM::HttpRequest.new(
16				"https://geocoder.ca/",
17				tls: { verify_peer: true }
18			).aget(query: { json: 1, locate: q }).then { |res|
19				JSON.parse(res.response)
20			}
21		}.then(&GeoCode.method(:for))
22	end
23
24protected
25
26	def cache(k, &blk)
27		k = "geocode_#{k.gsub(/ /, '%20')}"
28		promise = EMPromise.new
29		@memcache.get(k, &promise.method(:fulfill))
30		promise.then { |cbor|
31			CBOR.decode(cbor)
32		}.catch(&blk).then { |result|
33			@memcache.set(k, result.to_cbor)
34			result
35		}
36	end
37end