open-pod/lib/podcast_feed/boundary/archive_server.ex

72 lines
1.9 KiB
Elixir
Raw Normal View History

2020-06-07 21:37:41 +02:00
defmodule PodcastFeed.Boundary.ArchiveServer do
@moduledoc false
use GenServer, restart: :temporary
require Logger
alias PodcastFeed
alias PodcastFeed.Provider.Archive
@registry :podcast_registry
@archive_supervisor :archive_supervisor
##########
### API
def start_link(identifier) do
GenServer.start_link(__MODULE__, identifier, name: via(identifier))
end
def cache_or_fetch(identifier) do
case DynamicSupervisor.start_child(@archive_supervisor, {__MODULE__, identifier}) do
{:ok, pid} -> {:ok, pid}
{:error, {:already_started, pid}} -> {:ok, pid}
error -> error
end
# %{id: Worker, start: { Worker, :start_link, [child_name]}, restart: :transient})
end
def get_feed(identifier) do
cache_or_fetch(identifier)
GenServer.call(via(identifier), :get_feed)
end
def reload(identifier) do
GenServer.call(via(identifier), :reload)
end
##########
### SERVER
def init(identifier) do
{:ok, %{identifier: identifier, feed_data: fetch_feed_data(identifier)}}
end
def handle_call(:get_feed, _from, feed) do
Logger.debug "retrieve cached feed data for #{feed[:identifier]}..."
{:reply, feed[:feed_data], feed, Application.fetch_env!(:podcast_feed, :cache_duration)}
end
def handle_call(:reload, _from, feed) do
Logger.debug "discard cached feed data for #{feed[:identifier]}..."
feed_data = fetch_feed_data(feed[:identifier])
{:reply, feed_data, %{feed | feed_data: feed_data}}
end
def handle_info(:timeout, %{identifier: identifier}) do
Logger.debug "shutting down #{identifier}..."
{:stop, :normal, []}
end
##########
### PRIVATES
defp fetch_feed_data(identifier) do
Logger.debug "fetching archive metadata for #{identifier}..."
Archive.Parser.by_identifier(identifier)
end
defp via(identifier) do
{:via, Registry, {@registry, identifier}}
end
end