From 4637dde378fca0a4f0ea4e0037942478d1536f45 Mon Sep 17 00:00:00 2001 From: Eyal Lapid Date: Sat, 7 Mar 2026 14:26:48 +0200 Subject: [PATCH] docs: update README with practical usage examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace Kernel.:+ with System.version and System.cmd - Add anonymous function example with run_fun - Add RemoteHealth module example - Show progressive complexity: one-liners → closures → modules Closes #34 Co-Authored-By: Claude Opus 4.6 --- README.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6ae834e..57767e0 100644 --- a/README.md +++ b/README.md @@ -57,29 +57,74 @@ target = %Fusion.Target{ # Connect (sets up tunnels, bootstraps remote BEAM, joins cluster) {:ok, manager} = Fusion.NodeManager.start_link(target) {:ok, remote_node} = Fusion.NodeManager.connect(manager) +``` -# Run code remotely (MFA form) -{:ok, 3} = Fusion.run(remote_node, Kernel, :+, [1, 2]) +Run functions on the remote: -# Run system commands on the remote +```elixir +# Get remote system info +{:ok, version} = Fusion.run(remote_node, System, :version, []) {:ok, {hostname, 0}} = Fusion.run(remote_node, System, :cmd, ["hostname", []]) +``` + +Run anonymous functions directly: -# Push and run your own modules (dependencies are resolved automatically) -{:ok, result} = Fusion.run(remote_node, MyApp.Worker, :process, [data]) +```elixir +{:ok, info} = Fusion.run_fun(remote_node, fn -> + %{ + node: Node.self(), + otp: System.otp_release(), + os: :os.type() + } +end) +``` -# Disconnect and clean up +Push and run your own modules — dependencies are resolved automatically: + +```elixir +defmodule RemoteHealth do + def check do + %{ + hostname: hostname(), + elixir_version: System.version(), + memory_mb: memory_mb() + } + end + + defp hostname do + {name, _} = System.cmd("hostname", []) + String.trim(name) + end + + defp memory_mb do + {meminfo, _} = System.cmd("cat", ["/proc/meminfo"]) + + meminfo + |> String.split("\n") + |> Enum.find(&String.starts_with?(&1, "MemTotal")) + |> String.split(~r/\s+/) + |> Enum.at(1) + |> String.to_integer() + |> div(1024) + end +end + +{:ok, health} = Fusion.run(remote_node, RemoteHealth, :check, []) +# => %{hostname: "web-01", elixir_version: "1.18.4", memory_mb: 7982} +``` + +Disconnect when done: + +```elixir Fusion.NodeManager.disconnect(manager) ``` ### Automatic Dependency Resolution -When you run `MyApp.Worker` remotely, Fusion automatically pushes all project modules that `Worker` references (struct usage, function calls, etc.). You don't need to manually track the dependency chain. +When you run `RemoteHealth` remotely, Fusion reads the BEAM bytecode, walks the dependency tree, and pushes everything the module needs. You don't need to manually track the dependency chain. ```elixir -# This pushes MyApp.Worker AND any project modules it depends on -{:ok, result} = Fusion.run(remote_node, MyApp.Worker, :do_work, []) - -# You can also push explicitly +# You can also push modules explicitly Fusion.TaskRunner.push_module(remote_node, MyApp.Worker) Fusion.TaskRunner.push_modules(remote_node, [MyApp.Config, MyApp.Utils]) ```