archive_server.ex 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. defmodule PodcastFeed.Boundary.ArchiveServer do
  2. @moduledoc false
  3. use GenServer, restart: :temporary
  4. require Logger
  5. alias PodcastFeed
  6. alias PodcastFeed.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(identifier) do
  27. GenServer.call(via(identifier), :reload)
  28. end
  29. ##########
  30. ### SERVER
  31. def init(identifier) do
  32. {:ok, %{identifier: identifier, feed_data: fetch_feed_data(identifier)}}
  33. end
  34. def handle_call(:get_feed, _from, feed) do
  35. Logger.debug "retrieve cached feed data for #{feed[:identifier]}..."
  36. {:reply, feed[:feed_data], feed, Application.fetch_env!(:podcast_feed, :cache_duration)}
  37. end
  38. def handle_call(:reload, _from, feed) do
  39. Logger.debug "discard cached feed data for #{feed[:identifier]}..."
  40. feed_data = fetch_feed_data(feed[:identifier])
  41. {:reply, feed_data, %{feed | feed_data: feed_data}}
  42. end
  43. def handle_info(:timeout, %{identifier: identifier}) do
  44. Logger.debug "shutting down #{identifier}..."
  45. {:stop, :normal, []}
  46. end
  47. ##########
  48. ### PRIVATES
  49. defp fetch_feed_data(identifier) do
  50. Logger.debug "fetching archive metadata for #{identifier}..."
  51. Archive.Parser.by_identifier(identifier)
  52. end
  53. defp via(identifier) do
  54. {:via, Registry, {@registry, identifier}}
  55. end
  56. end