[英]Elixir fsm and Exactor takes ages to respond
我目前正在使用Nadia,fsm和Exactor構建聊天機器人。 我正在嘗試將每個用戶對話建模為一個有限狀態機,以獲取每個用戶當前所處的每個狀態的引用,並使用緩存在用戶聊天ID和其使用的fsm的相應pid之間進行引用。
我的設計基於本教程
以下代碼段創建了pid,但每當我嘗試轉換到下一個狀態時都會被卡住(輪詢)
defp create(id) do
{:ok, pid} = start_link()
Cache.get_or_create(:teleid2pid, id, pid)
IO.inspect "Changing to polling"
start_polling(pid, id)
pid
end
def pid_or_create(id) do
pid = Cache.get_value(:teleid2pid, id)
case pid do
nil -> create(id)
_ -> pid
end
end
我根據fsm庫的github頁面上的示例使用以下代碼創建可能的事件
@one_arity_events [:start_polling, :edit_info, :update_db]
for event <- @one_arity_events do
defcall unquote(event)(data), state: fsm do
FlowFsm.unquote(event)(fsm, data)
|> new_state
end
end
對於這個特定的例子,這就是我正在呼叫的事件
defstate start do
defevent start_polling(id) do
next_state(:polling, get_user_info(id))
end
end
但是get_user_info函數不會導致速度下降這是使用iEx的示例
iex(1)> alias TelegramBot.FsmServer
TelegramBot.FsmServer
iex(2)> alias TelegramBot.FlowFsm
TelegramBot.FlowFsm
iex(3)> pid = FsmServer.pid_or_create("1")
[debug] QUERY OK source="users" db=2.7ms decode=2.6ms
"Changing to polling"
** (exit) exited in: GenServer.call(#PID<0.334.0>, {:start_polling,"1"}, 5000)
** (EXIT) time out
(elixir) lib/gen_server.ex:774: GenServer.call/3
(backend)
lib/backend/telegram_chatbot/fsm/fsm_server.ex:19:
TelegramBot.FsmServer.create/1
iex(3)> pid = FsmServer.pid_or_create("1")
#PID<0.334.0>
iex(4)> FsmServer.state(pid)
:polling
iex(5)> FlowFsm.get_user_info("1")
%{db_id: 1, telegram_id: "1"}
如果我在不使用FsmServer的情況下調用它,FSM數據結構將自行工作。
是什么原因導致這種巨大的滯后? 或者更好的是,我如何同時管理多個FSM實例?
我在genserver內部調用了genserver,所以按照Dogbert的建議,它最終陷入了死鎖,為了解決這個問題,我修改了start_link並創建了這樣的函數
defstart start_link(id), do: initial_state(create_fsm(id))
defp create(id) do
{:ok, pid} = start_link(id)
Cache.get_or_create(:teleid2pid, id, pid)
pid
end
defp create_fsm(id) do
FlowFsm.new
|> FlowFsm.start_polling(id)
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.