Ir para o conteúdo principal

← todas as notas

📎 Webclip

Cross-App Communication with RPC in Elixir

Gearflow runs two Phoenix applications maintained by the same team and needed them to share data. Instead of an HTTP API, a message queue, or a shared database, they used distributed Erlang: nodes that share a secret cookie call each other’s functions directly through :rpc.call, reusing the same GraphQL schema and resolvers both apps already expose through Absinthe, just over a different transport.

The team names the cost up front. Calling into another app’s modules as if they were local creates implicit coupling: no API contract, no versioning, no compile-time warning when a remote function signature changes. Their bet is that catching an occasional breaking change quickly costs less than maintaining internal API infrastructure every day, given that the two apps already share a deploy pipeline and a Slack channel for coordinating releases.

Fichamento
#

  • The standard alternative, an internal API, was rejected for now: authentication between services, HTTP connection pools, retries, circuit breakers, schema versioning, and documentation are real costs that Gearflow judges premature at their current team size.
  • Node discovery, not the RPC call itself, was the harder problem. libcluster’s DNS-poll strategy failed because Fly.io appends an image hash to each node name, and the static basename it expects doesn’t account for that.
  • The fix was a custom libcluster strategy that resolves DNS to IPs, queries EPMD directly on each IP for the real node names, and filters by prefix to find the right ones.
  • The approach is scoped explicitly: both apps on the BEAM, both codebases under the team’s control, a trusted network (same Fly.io org, same VPC). Different languages, separate-team ownership, or an untrusted network boundary rule it out.
  • Production setup is a shared RELEASE_COOKIE secret across both Fly apps plus a pointer telling one app the other’s name; after that, nodes discover each other and a cross-app query is a single function call.
  • The migration path out, if the coupling bet stops paying off, is swapping :rpc.call for HTTP while keeping the same GraphQL queries.