Last active
December 13, 2017 19:54
-
-
Save christhekeele/1c0dc69d23931c69e1d50fc2fe9ca842 to your computer and use it in GitHub Desktop.
Revisions
-
christhekeele revised this gist
Dec 13, 2017 . 1 changed file with 15 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -17,19 +17,34 @@ defmodule Mnemonix.Stores.Meta.PassThrough do "bar" iex> Mnemonix.get(frontend, "foo") "bar" iex> Mnemonix.put(passthrough, "foo", "baz") iex> Mnemonix.get(frontend, "foo") "baz" iex> Mnemonix.get(backend, "foo") "baz" iex> Mnemonix.delete(passthrough, "foo") iex> Mnemonix.get(frontend, "foo") nil iex> Mnemonix.get(backend, "foo") nil iex> {nil, ^passthrough} = Mnemonix.get_and_update(passthrough, "foo", &({&1, {&1, &1}})) iex> Mnemonix.get(passthrough, "foo") {nil, nil} iex> Mnemonix.Stores.Meta.PassThrough.__info__(:functions) |> IO.inspect(limit: :infinity) #=> [bump: 3, bump!: 3, child_spec: 0, child_spec: 1, collectable_into: 2, #=> decrement: 2, decrement: 3, delete: 2, deserialize_key: 2, #=> deserialize_value: 2, do_bump: 4, do_bump_calculation: 3, drop: 2, #=> enumerable?: 1, enumerable_count: 1, enumerable_member?: 2, #=> enumerable_reduce: 3, fetch: 2, fetch!: 2, get: 2, get: 3, get_and_update: 3, #=> get_and_update!: 3, get_lazy: 3, has_key?: 2, increment: 2, increment: 3, #=> keys: 1, msg_for: 2, pop: 2, pop: 3, pop_lazy: 3, put: 3, put_new: 3, #=> put_new_lazy: 3, replace: 3, replace!: 3, serialize_key: 2, serialize_value: 2, #=> setup: 1, setup_initial: 1, split: 2, start_link: 0, start_link: 1, take: 2, #=> teardown: 2, to_enumerable: 1, to_list: 1, update: 4, update!: 3, values: 1] This store raises errors on the functions in `Mnemonix.Features.Enumerable`. """ -
christhekeele revised this gist
Dec 13, 2017 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -27,6 +27,9 @@ defmodule Mnemonix.Stores.Meta.PassThrough do nil iex> Mnemonix.get(backend, "foo") nil iex> {nil, ^passthrough} = Mnemonix.get_and_update(passthrough, "foo", &({&1, {&1, &1}})) iex> Mnemonix.get(passthrough, "foo") {nil, nil} This store raises errors on the functions in `Mnemonix.Features.Enumerable`. """ -
christhekeele revised this gist
Dec 13, 2017 . 1 changed file with 10 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -17,6 +17,16 @@ defmodule Mnemonix.Stores.Meta.PassThrough do "bar" iex> Mnemonix.get(frontend, "foo") "bar" iex> Mnemonix.put(passthrough, "foo", "baz") iex> Mnemonix.get(frontend, "foo") "baz" iex> Mnemonix.get(backend, "foo") "baz" iex> Mnemonix.delete(passthrough, "foo") iex> Mnemonix.get(frontend, "foo") nil iex> Mnemonix.get(backend, "foo") nil This store raises errors on the functions in `Mnemonix.Features.Enumerable`. """ -
christhekeele created this gist
Dec 13, 2017 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,89 @@ defmodule Mnemonix.Stores.Meta.PassThrough do @moduledoc """ A `Mnemonix.Store` that caches reads from a backend store into a frontend one. Writes and removals are applied to both stores. Works best with quicker or closer stores in the frontend, like in-memory ones; with a store-wide ttl to keep their footprint light. iex> {:ok, backend} = Mnemonix.Stores.Redix.start_link() iex> {:ok, frontend} = Mnemonix.Stores.ETS.start_link() iex> {:ok, passthrough} = Mnemonix.Stores.Meta.PassThrough.start_link(frontend: frontend, backend: backend) iex> Mnemonix.put(backend, "foo", "bar") iex> Mnemonix.get(frontend, "foo") nil iex> Mnemonix.get(passthrough, "foo") "bar" iex> Mnemonix.get(frontend, "foo") "bar" This store raises errors on the functions in `Mnemonix.Features.Enumerable`. """ alias Mnemonix.Store use Store.Behaviour use Store.Translator.Raw #### # Mnemonix.Store.Behaviours.Core ## @doc """ Tracks frontend and backend stores furnished in `opts`. ## Options - `frontend:` A store reference to cache reads from the backend store in. - `backend:` A store reference to use as the canonical uncached source of truth. """ @impl Store.Behaviours.Core @spec setup(Store.options()) :: {:ok, state :: term} | {:stop, reason :: any} def setup(opts) do {:ok, %{frontend: Keyword.fetch!(opts, :frontend), backend: Keyword.fetch!(opts, :backend)}} end #### # Mnemonix.Store.Behaviours.Map ## @impl Store.Behaviours.Map @spec delete(Store.t(), Mnemonix.key()) :: Store.Server.instruction() def delete(%Store{state: state} = store, key) do %{frontend: frontend, backend: backend} = state with ^frontend <- Mnemonix.delete(frontend, key), ^backend <- Mnemonix.delete(backend, key) do {:ok, store} end end @impl Store.Behaviours.Map @spec fetch(Store.t(), Mnemonix.key()) :: Store.Server.instruction({:ok, Mnemonix.value()} | :error) def fetch(%Store{state: state} = store, key) do %{frontend: frontend, backend: backend} = state if value = Mnemonix.get(frontend, key) do {:ok, store, {:ok, value}} else if value = Mnemonix.get(backend, key) do with ^frontend <- Mnemonix.put(frontend, key, value) do {:ok, store, {:ok, value}} end else {:ok, store, :error} end end end @impl Store.Behaviours.Map @spec put(Store.t(), Mnemonix.key(), Mnemonix.value()) :: Store.Server.instruction() def put(%Store{state: state} = store, key, value) do %{frontend: frontend, backend: backend} = state with ^frontend <- Mnemonix.put(frontend, key, value), ^backend <- Mnemonix.put(backend, key, value) do {:ok, store} end end end