94 خطوط
2.6 KiB
Elixir
94 خطوط
2.6 KiB
Elixir
defmodule Openpod.Boundary.ArchiveServer do
|
|
@moduledoc false
|
|
|
|
use GenServer, restart: :temporary
|
|
require Logger
|
|
alias Openpod
|
|
alias Openpod.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(pid) when is_pid(pid) do
|
|
Logger.debug "starting reload..."
|
|
GenServer.cast(pid, :reload)
|
|
end
|
|
|
|
def reload(identifier) do
|
|
cache_or_fetch(identifier)
|
|
GenServer.call(via(identifier), :reload)
|
|
end
|
|
|
|
def count(pid) when is_pid(pid) do
|
|
GenServer.call(pid, :count)
|
|
end
|
|
|
|
def count(identifier) when is_binary(identifier) do
|
|
GenServer.call(via(identifier), :count)
|
|
end
|
|
|
|
##########
|
|
### SERVER
|
|
|
|
def init(identifier) do
|
|
{:ok, %{count: 1, identifier: identifier, feed_data: fetch_feed_data(identifier)}}
|
|
end
|
|
|
|
def handle_call(:get_feed, _from, feed = %{count: count, feed_data: feed_data}) do
|
|
Logger.debug "retrieve cached feed data for #{feed[:identifier]}..."
|
|
{:reply, feed_data, %{feed | count: count + 1}, Application.fetch_env!(:openpod, :cache_duration)}
|
|
end
|
|
|
|
def handle_call(:reload, _from, feed = %{count: count, identifier: identifier}) do
|
|
Logger.debug "discard cached feed data for #{identifier}..."
|
|
feed_data = fetch_feed_data(identifier)
|
|
{:reply, feed_data, %{feed | count: count + 1, feed_data: feed_data}}
|
|
end
|
|
|
|
def handle_call(:count, _from, feed = %{identifier: identifier, count: count}) do
|
|
{:reply, %{identifier: identifier, count: count}, feed}
|
|
end
|
|
|
|
def handle_cast(:reload, feed = %{identifier: identifier}) do
|
|
Logger.debug "discard cached feed data for #{identifier}..."
|
|
{:noreply, %{feed | feed_data: fetch_feed_data(identifier)}}
|
|
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
|