feat: initial implementation
This commit is contained in:
parent
c7be19c9e1
commit
3917260030
2 changed files with 77 additions and 0 deletions
17
lib/init.ex
17
lib/init.ex
|
@ -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
60
test/init_test.exs
Normal 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
|
Loading…
Reference in a new issue