Skip to content

Commit

Permalink
Move redis into own process
Browse files Browse the repository at this point in the history
  • Loading branch information
Ian Vaughan committed Oct 5, 2018
1 parent 9d06f22 commit 5881802
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 25 deletions.
9 changes: 8 additions & 1 deletion lib/slot_sync/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ defmodule SlotSync.Application do

defp children do
with conf <- Map.new(config()) do
[:metrics_service, :shift_processor, :wiw_sync] |> Enum.flat_map(&children(&1, conf))
[:metrics_service, :shift_processor, :redis, :wiw_sync]
|> Enum.flat_map(&children(&1, conf))
end
end

Expand Down Expand Up @@ -47,4 +48,10 @@ defmodule SlotSync.Application do
}
]
end

defp children(:redis, _) do
[
worker(SlotSync.Cache.Redis, [])
]
end
end
51 changes: 51 additions & 0 deletions lib/slot_sync/cache/redis.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
defmodule SlotSync.Cache.Redis do
use GenServer

@spec start_link() :: :ignore | {:error, any()} | {:ok, pid()}
def start_link, do: GenServer.start_link(__MODULE__, [], name: __MODULE__)

def get(shift), do: GenServer.call(__MODULE__, {:get, shift})
def set(shift), do: GenServer.cast(__MODULE__, {:set, shift})
def del(shift), do: GenServer.cast(__MODULE__, {:del, shift})
def del_all, do: GenServer.cast(__MODULE__, {:del_all})

# Callbacks

@impl true
@spec init(any()) :: {:ok, pid()}
def init(_) do
{:ok, conn} = Redix.start_link("redis://localhost:6379/3", name: :redix)
{:ok, conn}
end

@impl true
def handle_call({:get, shift}, _caller, conn) do
{:ok, shift} = Redix.command(conn, ["GET", shift["id"]])

{:reply, decode(shift), conn}
end

@impl true
def handle_cast({:set, shift}, conn) do
{:ok, _shift} = Redix.command(conn, ["SET", shift["id"], shift |> Poison.encode!()])

{:noreply, conn}
end

@impl true
def handle_cast({:del, shift}, conn) do
{:ok, _shift} = Redix.command(conn, ["DEL", shift["id"]])

{:noreply, conn}
end

@impl true
def handle_cast({:del_all}, conn) do
# {:ok, _shift} = Redix.command(conn, ["SET", shift["id"], shift |> Poison.encode!()])

{:noreply, conn}
end

defp decode(nil), do: nil
defp decode(shift), do: shift |> Poison.decode!()
end
33 changes: 9 additions & 24 deletions lib/slot_sync/shift_processor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ defmodule SlotSync.Processor.Shift do

use GenServer

alias SlotSync.Cache.Redis

@spec start_link() :: :ignore | {:error, any()} | {:ok, pid()}
def start_link, do: GenServer.start_link(__MODULE__, [], name: __MODULE__)

Expand All @@ -50,47 +52,30 @@ defmodule SlotSync.Processor.Shift do

@impl true
@spec init(any()) :: {:ok, pid()}
def init(_) do
{:ok, conn} = Redix.start_link("redis://localhost:6379/3", name: :redix)
{:ok, conn}
end
def init(_), do: {:ok, %{}}

@impl true
def handle_cast({:process, shift}, conn) do
if in_redis?(shift, conn) do
def handle_cast({:process, shift}, state) do
if cached?(shift) do
stats("processor.shift.matched")
else
stats("processor.shift.unmatched")
redis_set(shift, conn)
Redis.set(shift)
publish(shift)
end

{:noreply, conn}
{:noreply, state}
end

defp in_redis?(shift, conn) do
md5(redis_get(shift, conn)) == md5(shift)
defp cached?(shift) do
md5(Redis.get(shift)) == md5(shift)
end

defp md5(data) do
:crypto.hash(:md5, Poison.encode!(data))
|> Base.encode16()
end

defp redis_get(shift, conn) do
{:ok, shift} = Redix.command(conn, ["GET", shift["id"]])

case shift do
nil -> nil
data -> Poison.decode!(data)
end
end

defp redis_set(shift, conn) do
{:ok, shift} = Redix.command(conn, ["SET", shift["id"], shift |> Poison.encode!()])
shift
end

defp publish(shift), do: publisher().call(shift, shift["id"])
defp publisher, do: config()[:publisher]

Expand Down

0 comments on commit 5881802

Please sign in to comment.