使用 GenServer 处理负载下的数据 (gen_server)
Processing data under load with GenServer (gen_server)
我正在 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)
吗?
有更好的方法吗?
我过去使用的一种技术是将数据发送到另一个 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
我正在 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)
吗?
有更好的方法吗?
我过去使用的一种技术是将数据发送到另一个 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