archive_server.ex 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. defmodule Openpod.Boundary.ArchiveServer do
  2. @moduledoc false
  3. use GenServer, restart: :temporary
  4. require Logger
  5. alias Openpod
  6. alias Openpod.Provider.Archive
  7. @registry :podcast_registry
  8. @archive_supervisor :archive_supervisor
  9. ##########
  10. ### API
  11. def start_link(identifier) do
  12. GenServer.start_link(__MODULE__, identifier, name: via(identifier))
  13. end
  14. def cache_or_fetch(identifier) do
  15. case DynamicSupervisor.start_child(@archive_supervisor, {__MODULE__, identifier}) do
  16. {:ok, pid} -> {:ok, pid}
  17. {:error, {:already_started, pid}} -> {:ok, pid}
  18. error -> error
  19. end
  20. # %{id: Worker, start: { Worker, :start_link, [child_name]}, restart: :transient})
  21. end
  22. def get_feed(identifier) do
  23. cache_or_fetch(identifier)
  24. GenServer.call(via(identifier), :get_feed)
  25. end
  26. def reload(pid) when is_pid(pid) do
  27. Logger.debug "starting reload..."
  28. GenServer.cast(pid, :reload)
  29. end
  30. def reload(identifier) do
  31. cache_or_fetch(identifier)
  32. GenServer.call(via(identifier), :reload)
  33. end
  34. def count(pid) when is_pid(pid) do
  35. GenServer.call(pid, :count)
  36. end
  37. def count(identifier) when is_binary(identifier) do
  38. GenServer.call(via(identifier), :count)
  39. end
  40. ##########
  41. ### SERVER
  42. def init(identifier) do
  43. {:ok, %{count: 1, identifier: identifier, feed_data: fetch_feed_data(identifier)}}
  44. end
  45. def handle_call(:get_feed, _from, feed = %{count: count, feed_data: feed_data}) do
  46. Logger.debug "retrieve cached feed data for #{feed[:identifier]}..."
  47. {:reply, feed_data, %{feed | count: count + 1}, Application.fetch_env!(:openpod, :cache_duration)}
  48. end
  49. def handle_call(:reload, _from, feed = %{count: count, identifier: identifier}) do
  50. Logger.debug "discard cached feed data for #{identifier}..."
  51. feed_data = fetch_feed_data(identifier)
  52. {:reply, feed_data, %{feed | count: count + 1, feed_data: feed_data}}
  53. end
  54. def handle_call(:count, _from, feed = %{identifier: identifier, count: count}) do
  55. {:reply, %{identifier: identifier, count: count}, feed}
  56. end
  57. def handle_cast(:reload, feed = %{identifier: identifier}) do
  58. Logger.debug "discard cached feed data for #{identifier}..."
  59. {:noreply, %{feed | feed_data: fetch_feed_data(identifier)}}
  60. end
  61. def handle_info(:timeout, %{identifier: identifier}) do
  62. Logger.debug "shutting down #{identifier}..."
  63. {:stop, :normal, []}
  64. end
  65. ##########
  66. ### PRIVATES
  67. defp fetch_feed_data(identifier) do
  68. Logger.debug "fetching archive metadata for #{identifier}..."
  69. Archive.Parser.by_identifier(identifier)
  70. end
  71. defp via(identifier) do
  72. {:via, Registry, {@registry, identifier}}
  73. end
  74. end