A client-side module used on remote/service nodes to push configurations to the PhoenixGenApi gateway/server node.
Unlike ConfigReceiver (which is a GenServer running on the server), this
module is a simple collection of functions that make RPC calls to the server
node. It does not maintain any state of its own.
RPC Communication
All functions use :rpc.call/5 to communicate with the server node. If the
server is unreachable or the RPC call fails, the result is wrapped in
{:error, {:badrpc, reason}}.
Typical Usage
Remote nodes should call push_on_startup/3 during their application start
(e.g., in the start/2 callback or a GenServer's init/handle_continue)
to register their service configuration with the gateway.
Example
alias PhoenixGenApi.Structs.{FunConfig, PushConfig}
alias PhoenixGenApi.ConfigPusher
fun_configs = [
%FunConfig{
request_type: "get_data",
service: :my_service,
nodes: [Node.self()],
choose_node_mode: :random,
timeout: 5_000,
mfa: {MyApp.Api, :get_data, []},
arg_types: %{"id" => :string},
response_type: :sync,
version: "1.0.0"
}
]
push_config = ConfigPusher.from_service_config(
:my_service,
[Node.self()],
fun_configs,
config_version: "1.0.0",
module: MyApp.GenApi.Supporter,
function: :get_config
)
# Push to gateway node
ConfigPusher.push_on_startup(:gateway@host, push_config)
# Or verify first
case ConfigPusher.verify(:gateway@host, :my_service, "1.0.0") do
{:ok, :matched} -> :already_registered
{:ok, :mismatch, _} -> ConfigPusher.push(:gateway@host, push_config)
{:error, :not_found} -> ConfigPusher.push(:gateway@host, push_config)
end
Summary
Functions
Helper to create a PushConfig from existing service configuration data.
Pushes configurations to the server node without options.
Pushes configurations to the server node.
Pushes configs and handles the "push once on startup" pattern.
Verifies that the server has the given service and config version without options.
Verifies that the server has the given service and config version.
Functions
@spec from_service_config( String.t() | atom(), [atom() | String.t()], [PhoenixGenApi.Structs.FunConfig.t()], keyword() ) :: PhoenixGenApi.Structs.PushConfig.t()
Helper to create a PushConfig from existing service configuration data.
This is a convenience function that builds a %PushConfig{} struct from the
individual components, handling the optional fields for auto-pull and version
checking.
Parameters
service- Service name (string or atom)nodes- List of node names (atoms or strings)fun_configs- List ofFunConfigstructsopts- Options keyword list::config_version- Config version string (required):module- Module for auto-pull (optional):function- Function for auto-pull (optional):args- Args for auto-pull (default:[]):version_module- Version check module (optional):version_function- Version check function (optional):version_args- Version check args (default:[])
Returns
A %PushConfig{} struct.
Raises
Raises ArgumentError if :config_version is not provided in opts.
Example
push_config = ConfigPusher.from_service_config(
:my_service,
[Node.self()],
fun_configs,
config_version: "1.0.0",
module: MyApp.GenApi.Supporter,
function: :get_config,
version_module: MyApp.GenApi.Supporter,
version_function: :get_config_version
)
@spec push(node(), PhoenixGenApi.Structs.PushConfig.t()) :: {:ok, :accepted} | {:ok, :skipped, term()} | {:error, term()}
Pushes configurations to the server node without options.
Convenience function that calls push/3 with default options.
Parameters
server_node- The node name (atom) of the PhoenixGenApi gatewaypush_config- A%PushConfig{}struct
Returns
Same as push/3.
@spec push(node(), PhoenixGenApi.Structs.PushConfig.t(), keyword()) :: {:ok, :accepted} | {:ok, :skipped, term()} | {:error, term()}
Pushes configurations to the server node.
Makes an RPC call to PhoenixGenApi.ConfigReceiver.push/2 on the server node.
The server validates the PushConfig, checks the version, and stores the
configs if the version is new (or if :force is set).
Parameters
server_node- The node name (atom) of the PhoenixGenApi gatewaypush_config- A%PushConfig{}structopts- Options keyword list::timeout- RPC timeout in ms (default: 5000):force- Force push even if version matches (default: false)
Returns
{:ok, :accepted}- New configs were stored successfully{:ok, :skipped, reason}- Push was skipped (e.g., version matches){:error, term()}- Push failed (includes:badrpcerrors)
Example
{:ok, :accepted} = ConfigPusher.push(:gateway@host, push_config, timeout: 10_000)
{:ok, :skipped, :version_matches} = ConfigPusher.push(:gateway@host, push_config)
{:error, {:badrpc, :nodedown}} = ConfigPusher.push(:unreachable@host, push_config)
@spec push_on_startup(node(), PhoenixGenApi.Structs.PushConfig.t(), keyword()) :: {:ok, :accepted} | {:ok, :skipped, term()} | {:error, term()}
Pushes configs and handles the "push once on startup" pattern.
This is the main entry point for remote nodes. It behaves the same as
push/3 but logs the result at info level with more prominent messaging,
making it easy to see in startup logs whether the configuration was
successfully registered.
Call this function in your application's start/2 callback or a GenServer's
handle_continue/2 to ensure your service is registered with the gateway
on startup.
Parameters
server_node- The node name (atom) of the PhoenixGenApi gatewaypush_config- A%PushConfig{}structopts- Options keyword list (same aspush/3)::timeout- RPC timeout in ms (default: 5000):force- Force push even if version matches (default: false)
Returns
Same as push/3.
Example
# In your application.ex
def start(_type, _args) do
# ... start your supervision tree, then:
ConfigPusher.push_on_startup(:gateway@host, push_config)
# ...
end
# Or in a GenServer
def init(opts) do
{:ok, initial_state, {:continue, :register_config}}
end
def handle_continue(:register_config, state) do
ConfigPusher.push_on_startup(:gateway@host, push_config)
{:noreply, state}
end
@spec verify(node(), String.t() | atom(), String.t()) :: {:ok, :matched} | {:ok, :mismatch, String.t()} | {:error, term()}
Verifies that the server has the given service and config version without options.
Convenience function that calls verify/4 with default options.
Parameters
server_node- The gateway nodeservice- Service name (string or atom)config_version- Expected config version string
Returns
Same as verify/4.
@spec verify(node(), String.t() | atom(), String.t(), keyword()) :: {:ok, :matched} | {:ok, :mismatch, String.t()} | {:error, term()}
Verifies that the server has the given service and config version.
Makes an RPC call to PhoenixGenApi.ConfigReceiver.verify/2 on the server
node. Useful for checking whether a push is necessary before sending the
full configuration.
Parameters
server_node- The gateway nodeservice- Service name (string or atom)config_version- Expected config version stringopts- Options::timeout- RPC timeout in ms (default: 5000)
Returns
{:ok, :matched}- Server has the same version{:ok, :mismatch, stored_version}- Server has a different version{:error, :not_found}- Service is not known on the server{:error, {:badrpc, reason}}- RPC call failed
Example
{:ok, :matched} = ConfigPusher.verify(:gateway@host, :my_service, "1.0.0")
{:ok, :mismatch, "0.9.0"} = ConfigPusher.verify(:gateway@host, :my_service, "1.0.0")
{:error, :not_found} = ConfigPusher.verify(:gateway@host, :unknown_service, "1.0.0")