feat: initial implementation

This commit is contained in:
sloane 2024-06-13 17:22:59 -04:00
parent c7be19c9e1
commit 3917260030
No known key found for this signature in database
2 changed files with 77 additions and 0 deletions

View file

@ -1,2 +1,19 @@
defmodule Init do defmodule Init do
@moduledoc """
Run a function synchronously as part of a `Supervisor`
"""
use GenServer, restart: :transient
def start_link(arg, opts \\ []) do
GenServer.start_link(__MODULE__, mfa!(arg), opts)
end
@impl true
def init({mod, fun, args}) do
apply(mod, fun, args)
:ignore
end
defp mfa!({_m, _f, _a} = mfa), do: mfa
defp mfa!(fun) when is_function(fun, 0), do: {Kernel, :apply, [fun, []]}
end end

60
test/init_test.exs Normal file
View file

@ -0,0 +1,60 @@
defmodule Echo do
def ping(pid, value, delay) do
Process.sleep(delay)
send(pid, value)
end
end
defmodule InitTest do
use ExUnit.Case, async: true
describe "when passed a module-function-arguments tuple" do
test "it runs to completion before other children of a Supervisor" do
children = [
Supervisor.child_spec({Init, {Echo, :ping, [self(), :foo, 20]}}, id: {Init, 1}),
Supervisor.child_spec({Init, {Echo, :ping, [self(), :bar, 10]}}, id: {Init, 2})
]
start_supervised!(%{
id: Supervisor,
start: {Supervisor, :start_link, [children, [strategy: :one_for_one]]}
})
assert_receive :foo
assert_receive :bar
end
end
describe "when passed a 0-arity anonymous function" do
test "it runs to completion before other children of a Supervisor" do
self = self()
children = [
Supervisor.child_spec(
{Init,
fn ->
Process.sleep(20)
send(self, :foo)
end},
id: {Init, 1}
),
Supervisor.child_spec(
{Init,
fn ->
Process.sleep(10)
send(self, :bar)
end},
id: {Init, 2}
)
]
start_supervised!(%{
id: Supervisor,
start: {Supervisor, :start_link, [children, [strategy: :one_for_one]]}
})
assert_receive :foo
assert_receive :bar
end
end
end