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
|
||||
@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
|
||||
|
|
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