72 lines
2.2 KiB
Elixir
72 lines
2.2 KiB
Elixir
defmodule Plausible.Workers.PurgeCDNCache do
|
|
@moduledoc """
|
|
Worker for purging CDN cache for tracker scripts on cloud.
|
|
|
|
Uses Bunny CDN's API to purge cache by tag.
|
|
Docs ref: https://docs.bunny.net/reference/pullzonepublic_purgecachepostbytag
|
|
|
|
Note that purging by id "*" is equivalent to purging ALL cache.
|
|
"""
|
|
|
|
use Oban.Worker,
|
|
queue: :purge_cdn_cache,
|
|
max_attempts: 5,
|
|
# To avoid running into API rate limits, we:
|
|
# - Schedule jobs with a delay
|
|
# - Bump the scheduled time every time a new one is scheduled with the same args
|
|
unique: [
|
|
states: [:scheduled],
|
|
fields: [:args]
|
|
]
|
|
|
|
require Logger
|
|
|
|
@impl Oban.Worker
|
|
def perform(%Oban.Job{args: %{"id" => id}}) do
|
|
pullzone_id = Application.get_env(:plausible, __MODULE__, [])[:pullzone_id]
|
|
api_key = Application.get_env(:plausible, __MODULE__, [])[:api_key]
|
|
|
|
purge_cache(id, pullzone_id, api_key)
|
|
end
|
|
|
|
@impl Oban.Worker
|
|
def backoff(%Oban.Job{attempt: attempt}) do
|
|
# Exponential backoff starting at 3 minutes
|
|
trunc(:math.pow(2, attempt - 1) * 180)
|
|
end
|
|
|
|
defp purge_cache(id, pullzone_id, api_key) when is_nil(pullzone_id) or is_nil(api_key) do
|
|
Logger.warning("Ignoring purge CDN cache for tracker script #{id}: Configuration missing")
|
|
{:discard, "Configuration missing"}
|
|
end
|
|
|
|
defp purge_cache(id, pullzone_id, api_key) do
|
|
options =
|
|
[
|
|
headers: [
|
|
{"content-type", "application/json"},
|
|
{"AccessKey", api_key}
|
|
],
|
|
body: Jason.encode!(%{"CacheTag" => "tracker_script::#{id}"})
|
|
]
|
|
|> Keyword.merge(Application.get_env(:plausible, __MODULE__)[:req_opts] || [])
|
|
|
|
case Req.post("https://api.bunny.net/pullzone/#{pullzone_id}/purgeCache", options) do
|
|
{:ok, %{status: 204}} ->
|
|
Logger.notice("Successfully purged CDN cache for tracker script #{id}")
|
|
{:ok, :success}
|
|
|
|
{:ok, %{status: status}} ->
|
|
Logger.warning(
|
|
"Failed to purge CDN cache for tracker script #{id}: Unexpected status: #{status}"
|
|
)
|
|
|
|
{:error, "Unexpected status: #{status}"}
|
|
|
|
{:error, reason} ->
|
|
Logger.warning("Failed to purge CDN cache for tracker script #{id}: #{inspect(reason)}")
|
|
{:error, reason}
|
|
end
|
|
end
|
|
end
|