aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlthms <contact@thomasletan.fr>2017-12-31 11:18:31 +0000
committerThomas Letan <contact@thomasletan.fr>2018-01-24 08:11:29 +0100
commitb7d54fbbf0e01802ed224f2e6239ab3da334ff2e (patch)
tree68a47be0319abf5167898416092dbd3f35fca0e2
parentrelease: lkn_core 0.3.0 (diff)
fix: (Un)registering puppets blocks to avoid range race conditions
-rw-r--r--lib/lkn/core/instance.ex9
-rw-r--r--lib/lkn/core/system.ex30
2 files changed, 19 insertions, 20 deletions
diff --git a/lib/lkn/core/instance.ex b/lib/lkn/core/instance.ex
index 0bc7928..6e223ed 100644
--- a/lib/lkn/core/instance.ex
+++ b/lib/lkn/core/instance.ex
@@ -233,9 +233,9 @@ defmodule Lkn.Core.Instance do
as at least one Puppeteer stays registered (and it will probably do nothing at
all).
"""
- @spec unregister_puppet(k, Puppet.k) :: :ok
+ @spec unregister_puppet(k, Puppet.k) :: boolean
def unregister_puppet(instance_key, puppet_key) do
- GenServer.cast(Lkn.Core.Name.instance(instance_key), {:unregister_puppet, puppet_key})
+ GenServer.call(Lkn.Core.Name.instance(instance_key), {:unregister_puppet, puppet_key})
end
@doc false
@@ -340,8 +340,7 @@ defmodule Lkn.Core.Instance do
{:reply, true, state}
end
end
-
- def handle_cast({:unregister_puppet, puppet_key}, state) do
+ def handle_call({:unregister_puppet, puppet_key}, _from, state) do
state = if MapSet.member?(state.puppets, puppet_key) do
# unregister the pupet from each systems
sys_map = Entity.systems(puppet_key)
@@ -367,7 +366,7 @@ defmodule Lkn.Core.Instance do
state
end
- {:noreply, state}
+ {:reply, true, state}
end
def handle_cast(:kick_all, state) do
State.kick_all(state)
diff --git a/lib/lkn/core/system.ex b/lib/lkn/core/system.ex
index 53ca6c7..aa8577a 100644
--- a/lib/lkn/core/system.ex
+++ b/lib/lkn/core/system.ex
@@ -263,27 +263,27 @@ defmodule Lkn.Core.System do
State.notify(priv, notification)
[priv: priv, pub: pub]
end
- defp priv_handle_cast({:register_puppet, entity_key}, priv: priv, pub: pub) do
- {priv, pub} = if Lkn.Core.Entity.has_component?(entity_key, __MODULE__) do
- {State.put(priv, entity_key), puppet_enter(pub, priv.instance_key, priv.map_key, priv.puppets, entity_key)}
+
+ defp priv_handle_call({:register_puppet, entity_key}, _from, priv: priv, pub: pub) do
+ {res, priv, pub} = if Lkn.Core.Entity.has_component?(entity_key, __MODULE__) do
+ {true, State.put(priv, entity_key), puppet_enter(pub, priv.instance_key, priv.map_key, priv.puppets, entity_key)}
else
- {priv, pub}
+ {false, priv, pub}
end
- [priv: priv, pub: pub]
+ {:reply, res, [priv: priv, pub: pub]}
end
- defp priv_handle_cast({:unregister_puppet, entity_key}, priv: priv, pub: pub) do
- {priv, pub} =
+ defp priv_handle_call({:unregister_puppet, entity_key}, _from, priv: priv, pub: pub) do
+ {res, priv, pub} =
if Lkn.Core.Entity.has_component?(entity_key, __MODULE__) do
priv = State.delete(priv, entity_key)
- {priv, puppet_leave(pub, priv.instance_key, priv.map_key, priv.puppets, entity_key)}
+ {true, priv, puppet_leave(pub, priv.instance_key, priv.map_key, priv.puppets, entity_key)}
else
- {priv, pub}
+ {false, priv, pub}
end
- [priv: priv, pub: pub]
+ {:reply, res, [priv: priv, pub: pub]}
end
-
defp priv_handle_call(:population_size, _from, priv: priv, pub: pub) do
{:reply, State.population(priv), [priv: priv, pub: pub]}
end
@@ -328,15 +328,15 @@ defmodule Lkn.Core.System do
end
@doc false
- @spec register_puppet(Instance.k, m, Puppet.k) :: :ok
+ @spec register_puppet(Instance.k, m, Puppet.k) :: boolean
def register_puppet(instance_key, system, puppet_key) do
- GenServer.cast(Name.system(instance_key, system), {:priv, {:register_puppet, puppet_key}})
+ GenServer.call(Name.system(instance_key, system), {:priv, {:register_puppet, puppet_key}})
end
@doc false
- @spec unregister_puppet(Instance.k, m, Puppet.k) :: :ok
+ @spec unregister_puppet(Instance.k, m, Puppet.k) :: boolean
def unregister_puppet(instance_key, system, puppet_key) do
- GenServer.cast(Name.system(instance_key, system), {:priv, {:unregister_puppet, puppet_key}})
+ GenServer.call(Name.system(instance_key, system), {:priv, {:unregister_puppet, puppet_key}})
end
@doc """