我正在GenServer中测试以下模式:
def handle_info({:tcp, _, data}, s) do
# IO.puts "\nrx: \n#{Base.encode16(data)}\n"
extra = _proc_data(<<s.extra::binary, data::binary>>)
:inet.setopts(s.socket, active: :once)
{:noreply, %{s | extra: extra}}
end
当数据快速进入时出现问题,我无法在:inet.setopts(s.socket, active: :once)
发布新数据之前更新状态
{:noreply, %{s | extra: extra}}
必须handle_info
是:inet.setopts(s.socket, active: :once)
的最后一行,还是可以最后执行<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
</namespaces>
?
有更好的方法吗?
答案 0 :(得分:1)
我过去使用的一种技术是将数据发送到另一个GenServer
进行处理。这将允许当前进程更快地调用:inet.setopts(s.socket, active: :once)
。
def handle_info({:tcp, _, data}, s) do
# IO.puts "\nrx: \n#{Base.encode16(data)}\n"
GenServer.cast(s.processor, {:data, data})
:inet.setopts(s.socket, active: :once)
{:noreply, s}
end
处理器:
defmodule DataProcessor do
use GenServer
def start_link(opts), do: GenServer.start_link(__MODULE__, [], opts)
def init(_), do: {:ok, %{}}
def handle_cast({:data, data}, state) do
extra = _proc_data(s.extra <> data)
{:noreply, %{state| extra: extra}}
end
defp _proc_data(data) do
...
end
end