PhoenixGenApi.ConfigPuller (PhoenixGenApi v2.8.0)

Copy Markdown View Source

This module is responsible for periodically pulling function configurations (%FunConfig{}) from remote nodes and updating the ConfigDb.

The puller's behavior can be configured in your config.exs file:

config :phoenix_gen_api, :gen_api,
  pull_timeout: 5_000,
  pull_interval: 30_000
  • pull_timeout: The timeout for each RPC call in milliseconds (default: 5000).
  • pull_interval: The interval between each pull operation in milliseconds (default: 30000).

Version-Based Skip Mechanism

When a ServiceConfig has version_module and version_function configured, the puller will first call the lightweight version check RPC before performing a full config pull. If the returned version matches the locally stored version for that service, the full pull is skipped — saving network bandwidth and reducing load on remote nodes.

The remote service should implement a version function that returns a value that changes whenever the function configurations change. Good candidates include:

  • A monotonically increasing integer (e.g., 1, 2, 3)
  • A semantic version string (e.g., "1.2.3")
  • A content hash of the config data (e.g., "a1b2c3d4")
  • A timestamp of the last config change (e.g., "2024-01-15T10:30:00Z")

The version value is compared using strict equality (==), so any format that can be compared this way will work.

If version_module or version_function is nil, version checking is disabled and the full config pull will always be performed (backward compatible behavior).

Use force_pull/0 to force a full pull regardless of version matching, which clears all stored versions and re-fetches every service's configuration.

Fault Tolerance

  • Failed RPC calls are logged and do not crash the puller
  • Node lists are validated before use
  • Configuration validation prevents invalid configs from entering the cache
  • Exponential backoff on repeated failures (up to a maximum)
  • Version check failures fall back to full pull

Security

  • Validates that remote configs match the expected service name
  • Validates FunConfig structs before adding to cache
  • Rejects configs with invalid MFAs or node configurations

Summary

Functions

Adds a list of services to the puller. The services argument must be a list of %ServiceConfig{} structs.

Returns a specification to start this module under a supervisor.

Deletes a list of services from the puller. The services argument must be a list of %ServiceConfig{} structs.

Forces an immediate full pull of configurations from all registered services, ignoring version checking. This clears all stored versions first, so every service will be re-fetched regardless of whether its version has changed.

Returns a map of all stored service versions.

Returns the list of APIs for a given service.

Returns the stored config version for a given service.

Returns the map of services currently being pulled from.

Triggers an immediate pull of configurations from the registered services. Version checking is respected — if the stored version matches the remote version, the full pull for that service is skipped.

Starts the ConfigPuller GenServer.

Functions

add(services)

Adds a list of services to the puller. The services argument must be a list of %ServiceConfig{} structs.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

delete(services)

Deletes a list of services from the puller. The services argument must be a list of %ServiceConfig{} structs.

Deleting a service also removes its stored version and API list entry.

force_pull()

Forces an immediate full pull of configurations from all registered services, ignoring version checking. This clears all stored versions first, so every service will be re-fetched regardless of whether its version has changed.

Use this when you want to guarantee a fresh configuration pull, for example after a deployment or when you suspect the local cache is stale.

get_all_versions()

@spec get_all_versions() :: %{required(String.t() | atom()) => term()}

Returns a map of all stored service versions.

The map keys are service names and the values are the stored version terms. Services that were pulled without version checking configured will have nil as their version value.

get_api_list(service)

Returns the list of APIs for a given service.

get_service_version(service)

@spec get_service_version(String.t() | atom()) :: term() | nil

Returns the stored config version for a given service.

Returns nil if no version has been stored for the service. This indicates that either the service hasn't been pulled yet, or version checking is not configured for the service and no version was captured from a previous pull.

get_services()

Returns the map of services currently being pulled from.

pull()

Triggers an immediate pull of configurations from the registered services. Version checking is respected — if the stored version matches the remote version, the full pull for that service is skipped.

start_link(opts \\ [])

Starts the ConfigPuller GenServer.