我无法在OTP中使用HashDict
函数。我想对GenServer
使用一个put
进程,对fetch
使用不同的进程。当我尝试实现此功能时,可以在从同一GenServer进行调用时从HashDict
中放入和获取项目。效果很好(在下面的示例中为MyServerA
)。但是,当我将一个GenServer
用作put
而将另一个fetch
用作HashDict
时,提取实现不起作用。为什么是这样?大概是因为我需要在三个不同的进程之间传递MyServerB
数据结构?
下面的代码示例:
我使用一个简单的调用将一些状态发送到MyServerB
:
MyServerA.add_update(state)
对于
HashDict
,我实现了MyServerB.get_state(dict,some_key)
,如下所示:defmodule MyServerB do
use GenServer
def start_link do
GenServer.start_link(__MODULE__,[], name: __MODULE__)
end
def init([]) do
#Initialise HashDict to store state
d = HashDict.new
{:ok, d}
end
#Client API
def add_update(update) do
GenServer.cast __MODULE__, {:add, update}
end
def get_state(window) do
GenServer.call __MODULE__, {:get, key}
end
# Server APIs
def handle_cast({:add, update}, dict) do
%{key: key} = update
dict = HashDict.put(dict, key, some_Value)
{:noreply, dict}
end
def handle_call({:get, some_key}, _from, dict) do
value = HashDict.fetch!(dict, some_key)
{:reply, value, dict}
end
end
因此,如果从另一个进程中我使用
HashDict
,则似乎无法返回cast
的内容...更新:
因此,如果我使用ETS,我会得到以下信息:
def init do
ets = :ets.new(:my_table,[:ordered_set, :named_table])
{:ok, ets}
end
def handle_cast({:add, update}, state) do
update = :ets.insert(:my_table, {key, value})
{:noreply, ups}
end
def handle_call({:get, some_key}, _from, state) do
sum = :ets.foldl(fn({{key},{value}}, acc)
when key == some_Key -> value + acc
(_, acc) ->
acc
end, 0, :my_table)
{:reply, sum, state}
end
因此,
observer
仍然有效-当我检查call
时,我可以看到它填充了我的键值对。但是,当我尝试ojit_code时,它再也没有返回任何内容。所以我想知道我是否处理不正确的状态?任何帮助,感激不尽?谢谢
最佳答案
您的问题在于以下语句:
在Elixir中,进程无法共享状态。因此,您不能让一个进程处理数据,而另一个进程直接读取数据。例如,您可以将HashDict存储在一个进程中,然后让另一个进程向第一个进程发送消息以询问数据。这将使它如您所描述的那样显示,但是在幕后它仍然会使所有事务都经过第一个过程。有一些技术可以以分布式/并发方式执行此操作,以便利用多个内核,但这可能比您目前打算做的工作还要多。
看一下ETS,它将允许您创建一个公共(public)表并从多个进程访问数据。
关于dictionary - Elixir中的HashDict和OTP GenServer上下文,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34271159/