PhoenixKit.KnownPackages (phoenix_kit v1.7.236)

Copy Markdown View Source

Live catalog of known external PhoenixKit packages fetched from Hex.pm.

Fetched on demand and cached in an ETS table for 10 minutes. On Hex failure, returns stale cached data when within the 24h max-stale-age cap, otherwise returns extra_known_packages config entries only.

Cache uses an ETS named table (:phoenix_kit_known_packages_cache) with read_concurrency: true rather than :persistent_term, to avoid global-GC write amplification on multi-node cold deploys.

Public API

list/1 accepts opts (intended for tests, not production):

  • :ttl_ms — cache TTL (default :timer.minutes(10))
  • :max_stale_age_ms — how long stale data may be served on Hex failure (default :timer.hours(24))
  • :req_options — pass-through to Req.get/2

Operational signals

Hex outages emit Logger entries at three levels — each maps to a distinct degradation state operators can alert on:

  • :warning "Hex fetch failed … serving stale data" — cache hit within max_stale_age_ms. Catalog still works; Hex briefly unavailable. Transient.
  • :warning "Hex fetch failed … no cached data" — Hex unreachable AND cache empty. Catalog shows config extras only. Visible degradation, but not a crisis (admin Modules page is the only consumer).
  • :error "Hex fetch failed … exceeds max stale age" — Hex unreachable for over max_stale_age_ms. Cached entries dropped, catalog falls back to config extras. The escalation level: page on this if it persists.

Summary

Functions

The human equivalent of the search this module runs against the Hex API.

Clears the in-process cache. Intended for tests.

Returns the list of known external PhoenixKit packages.

Whether the last catalog read reached hex.pm.

Functions

browse_url()

@spec browse_url() :: String.t()

The human equivalent of the search this module runs against the Hex API.

Offered when hex.pm is unreachable: a link stays current because Hex maintains it, where a catalog bundled into core would need a core release to add a package and would drift permanently.

clear_cache()

@spec clear_cache() :: :ok

Clears the in-process cache. Intended for tests.

list(opts \\ [])

@spec list(keyword()) :: [map()]

Returns the list of known external PhoenixKit packages.

Each entry is a map with keys: key, module, package, hex_package, name, description, icon, hex_url, github_url, latest_version, source.

See module doc for opts.

status()

@spec status() :: :ok | {:stale, non_neg_integer()} | :unavailable

Whether the last catalog read reached hex.pm.

:ok — fresh data. {:stale, age_minutes} — hex.pm was unreachable but cached data is still being served. :unavailable — unreachable with nothing usable cached, so list/1 returned config extras only.

The UI needs this because "hex.pm is down" and "there are no packages" produce the same empty list, and showing the second when the first is true tells the operator something false.