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
|
2020-06-07 23:10:40 +02:00
|
|
|
cache_or_fetch(identifier)
|
2020-06-07 21:37:41 +02:00
|
|
|
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
|