为什么我的GenServer handle_cast没有被调用

问题描述 投票:0回答:1

我在我的模块中使用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控制台的输出。建立数据库连接但是当我调用handle_cast方法时不调用put。我的实施有什么问题?

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
elixir gen-server
1个回答
0
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.