Ich baue gerade einen Chatbot mit Nadia, FMS und Exactor. Ich versuche, jede Benutzerkonversation als eine endliche Zustandsmaschine zu modellieren, um einen Bezug auf jeden Zustand zu haben, in dem sich jeder Benutzer gerade befindet, und einen Cache zu verwenden, um einen Bezug zwischen der Benutzer-Chat-ID und der entsprechenden pid der verwendeten fsm zu haben.Elixir fsm und Exactor braucht ewig zu reagieren
I basiert mein Design auf this tutorial
folgenden Ausschnitt der pid schafft, aber es stecken bleibt, wenn ich versuche, in den nächsten Zustand (Polling)
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
Ich schaffe die möglichen Ereignisse für den Übergang der Verwendung folgender Code basierend auf dem Beispiel auf den fsm library's github page
gefunden@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
Und für dieses Beispiel ist dies t er Fall, dass ich
defstate start do
defevent start_polling(id) do
next_state(:polling, get_user_info(id))
end
end
Aufruf Aber die get_user_info Funktion verursacht nicht die Verlangsamung Dies ist ein Beispiel unter Verwendung von 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"}
Die FSM-Datenstruktur von selbst funktioniert, wenn ich es so nennen, ohne Nutzen Sie den FsmServer.
Was könnte diese massive Verzögerung verursachen? Oder noch besser, wie könnte ich mehrere Instanzen von FSM gleichzeitig verwalten?
Sieht aus wie ein [Deadlock] (https : //en.wikipedia.org/wiki/Deadlock). Was macht 'start_polling'? Können Sie den kompletten Code dieses Moduls posten? – Dogbert
Ich habe es gerade mit ein paar mehr Informationen aktualisiert und diese Eiltebin des FsmServer-Moduls und der Fsm-Datenstruktur hinzugefügt. https://hastebin.com/simetibave.sql – user2070502
Ich habe noch nie verwendet EXACTOR so die Syntax mir fremd ist, aber dieses Problem in der Regel passiert, wenn Sie einen GenServer 'call' aus einem anderen' call' oder 'Besetzung machen '. Da nur eine Nachricht gleichzeitig verarbeitet wird, wird der zweite Aufruf nicht ausgeführt, bevor der aktuelle beendet wird, was zu einem Timeout führt. – Dogbert