Skip to content

Instantly share code, notes, and snippets.

@marinho10
Created February 14, 2019 18:55
Show Gist options
  • Save marinho10/b07f47d3c4de259e38220831962ef6f5 to your computer and use it in GitHub Desktop.
Save marinho10/b07f47d3c4de259e38220831962ef6f5 to your computer and use it in GitHub Desktop.
defmodule MyApp.TaskWorker do
use GenServer, restart: :transient
alias MyApp.Notify
alias MyApp.Management
alias MyApp.WorkerStateStorage
# client
def start_link(state) do
GenServer.start_link(__MODULE__, state)
end
# server
def init(state) do
state = Map.put(state, :pid, :erlang.pid_to_list(self()))
schedule_notify_task(300000)
case WorkerStateStorage.save(state) do
true ->
{:ok, state}
false ->
case WorkerStateStorage.get(state.task_id) do
nil ->
{:ok, state}
pid ->
stop(:erlang.list_to_pid(pid), state.task_id)
WorkerStateStorage.save(state)
{:ok, state}
end
end
end
def handle_info(:schedule_notify_task, state) do
case notify(state) do
true ->
stop(self(), state.task_id)
false ->
# Reschedule once more
schedule_notify_task(300000)
end
{:noreply, state}
end
def handle_cast(
{:notify_task},
state
) do
case notify(state) do
true ->
WorkerStateStorage.delete(state.task_id)
{:stop, :normal, state}
false ->
{:noreply, state}
end
end
defp schedule_notify_task(time) do
Process.send_after(self(), :schedule_notify_task, time)
end
defp notify(%{task_id: task_id, pid: pid} = state) do
task = Management.get_task!(task_id)
case task.is_open do
false ->
Notify.notify(task)
true ->
true
end
end
defp stop(pid, task_id) do
WorkerStateStorage.delete(task_id)
if Process.alive?(pid) do
Process.exit(pid, :normal)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment