【问题标题】:Why doesn't my GenServer handle_cast get called为什么我的 GenServer handle_cast 没有被调用
【发布时间】:2023-03-07 10:40:01
【问题描述】:

我在我的模块中使用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

【问题讨论】:

  • 我认为你需要从init/1返回{:ok, {conn, hkey}}
  • 首先使用start_link - 如果您知道自己在做什么,请仅使用start,默认情况下您希望拥有链接进程。我没有完全理解这个问题 - 您的 REPL 会话显示了正确的行为。怎么了?
  • start_linkstart 有什么区别?问题是 handle_cast 没有被调用,@Justin_Wood 给出了正确的答案。
  • @ZhaoYi start 只会启动新进程。 start_link 将启动新进程并将其链接到当前进程。该链接意味着如果新进程因任何异常原因死亡或崩溃,将通知当前进程。你可以阅读更多here
  • @JustinWood 很高兴知道,谢谢

标签: elixir gen-server


【解决方案1】:

您的GenServer 实际上并未运行。如果您要运行以下代码,您将得到相同的结果。

iex(1)> {:ok, pid} = RedisClient.start(url, pwd, hkey)
iex(2)> Process.alive?(pid)
false

问题是您从GenServerinit/1 回调中返回了一个三元素元组。第三个选项应该是超时。您的GenServer 在启动时会崩溃,因为hkey 没有保持有效的超时值。

在您的情况下,您需要返回 {:ok, {conn, hkey}}

【讨论】:

    猜你喜欢
    • 2021-03-03
    • 2019-12-17
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2022-10-15
    相关资源
    最近更新 更多