为什么我的 GenServer handle_cast 没有被调用
Why doesn't my GenServer handle_cast get called
我在我的模块中使用 GenServer
,如下所示。在 init 方法中,它创建到数据库的 redis 连接。 put
方法将发送要保存在 redisdb 中的值。 handle_cast
方法会在redis连接上调用命令进行数据库操作。
defmodule RedisClient do
use GenServer
require Logger
# Client
def start(url, pwd, hkey) do
GenServer.start(__MODULE__, {url, pwd, hkey});
end
def init({url, pwd, hkey}) do
Logger.info("connect to url #{url} #{pwd} #{hkey}");
case Redix.start_link(url) do
{:ok, conn} -> case Redix.command(conn, ["auth", pwd]) do
{:ok, message} -> {:ok, conn, hkey}
_ -> {:error}
end
end
end
def put(pid, field, value) do
Logger.info("put #{field} #{value}")
GenServer.cast(pid, {:hset, field, value})
end
def handle_cast({:hset, field, value}, {conn, hkey}) do
Logger.info("write to database #{field} #{value}")
result = Redix.command(conn, ["hset", hkey, field, value]);
{:noreply, {conn, hkey}}
end
end
下面是 iex
控制台的输出。数据库连接已建立,但在调用 put
方法时未调用 handle_cast
。我的实施有什么问题?
iex(tbc@192-168-1-7)85> {:ok, pid} = RedisClient.start("redis://localhost", "mypassword", "mykey")
{:ok, #PID<0.23038.0>}
iex(tbc@192-168-1-7)86>
11:19:49.554 [info] connect to url redis://localhost mypassword mykey
iex(tbc@192-168-1-7)87> RedisClient.put(pid, "field1", "value1")
:ok
iex(tbc@192-168-1-7)88>
11:20:26.429 [info] put field1 value1
你的 GenServer
实际上不是 运行ning。如果您要 运行 以下代码,您将得到相同的结果。
iex(1)> {:ok, pid} = RedisClient.start(url, pwd, hkey)
iex(2)> Process.alive?(pid)
false
问题是您正在从 GenServer
的 init/1
回调中 return 创建一个三元素元组。第三个选项应该是超时。您的 GenServer
在启动时崩溃,因为 hkey
没有持有有效的超时值。
在您的情况下,您需要 return {:ok, {conn, hkey}}
。
我在我的模块中使用 GenServer
,如下所示。在 init 方法中,它创建到数据库的 redis 连接。 put
方法将发送要保存在 redisdb 中的值。 handle_cast
方法会在redis连接上调用命令进行数据库操作。
defmodule RedisClient do
use GenServer
require Logger
# Client
def start(url, pwd, hkey) do
GenServer.start(__MODULE__, {url, pwd, hkey});
end
def init({url, pwd, hkey}) do
Logger.info("connect to url #{url} #{pwd} #{hkey}");
case Redix.start_link(url) do
{:ok, conn} -> case Redix.command(conn, ["auth", pwd]) do
{:ok, message} -> {:ok, conn, hkey}
_ -> {:error}
end
end
end
def put(pid, field, value) do
Logger.info("put #{field} #{value}")
GenServer.cast(pid, {:hset, field, value})
end
def handle_cast({:hset, field, value}, {conn, hkey}) do
Logger.info("write to database #{field} #{value}")
result = Redix.command(conn, ["hset", hkey, field, value]);
{:noreply, {conn, hkey}}
end
end
下面是 iex
控制台的输出。数据库连接已建立,但在调用 put
方法时未调用 handle_cast
。我的实施有什么问题?
iex(tbc@192-168-1-7)85> {:ok, pid} = RedisClient.start("redis://localhost", "mypassword", "mykey")
{:ok, #PID<0.23038.0>}
iex(tbc@192-168-1-7)86>
11:19:49.554 [info] connect to url redis://localhost mypassword mykey
iex(tbc@192-168-1-7)87> RedisClient.put(pid, "field1", "value1")
:ok
iex(tbc@192-168-1-7)88>
11:20:26.429 [info] put field1 value1
你的 GenServer
实际上不是 运行ning。如果您要 运行 以下代码,您将得到相同的结果。
iex(1)> {:ok, pid} = RedisClient.start(url, pwd, hkey)
iex(2)> Process.alive?(pid)
false
问题是您正在从 GenServer
的 init/1
回调中 return 创建一个三元素元组。第三个选项应该是超时。您的 GenServer
在启动时崩溃,因为 hkey
没有持有有效的超时值。
在您的情况下,您需要 return {:ok, {conn, hkey}}
。