diff options
author | lthms <contact@thomasletan.fr> | 2017-12-31 11:18:31 +0000 |
---|---|---|
committer | Thomas Letan <contact@thomasletan.fr> | 2018-01-24 08:11:29 +0100 |
commit | b7d54fbbf0e01802ed224f2e6239ab3da334ff2e (patch) | |
tree | 68a47be0319abf5167898416092dbd3f35fca0e2 | |
parent | release: lkn_core 0.3.0 (diff) |
fix: (Un)registering puppets blocks to avoid range race conditions
-rw-r--r-- | lib/lkn/core/instance.ex | 9 | ||||
-rw-r--r-- | lib/lkn/core/system.ex | 30 |
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 """ |