Packages

Yalo tester of conversations for Elixir.

Current section

Files

Jump to
Raw

lib/worker.ex

defmodule YaloTestConversation.Worker do
@moduledoc """
Documentation for Worker
"""
require Logger
use GenServer
def start_link(bot, messages, activity, id) do
GenServer.start_link(__MODULE__, [bot, messages, activity, id], name: String.to_atom(id))
end
def init([bot, messages, activity, id]) do
start = NaiveDateTime.utc_now()
state = %{
id: id,
bot: bot,
messages: messages,
start: start,
activity: activity,
attempts: 0
}
Logger.info("INIT WORKER #{inspect(state.id)}")
send(self(), :send_message)
{:ok, state}
end
def send_message(current_message, state) do
env = Application.get_all_env(:yalo_test_conversation)
Logger.info("SENDING.... #{inspect(current_message["message"])}")
headers = [{"Content-Type", "application/json"}]
IO.inspect(
"#{env[:hooks_proxy]}/botrunner?callback-url=#{env[:callback_url]}?pid=#{state.id}"
)
case HTTPoison.request(
"POST",
"#{env[:hooks_proxy]}/botrunner?callback-url=#{env[:callback_url]}?pid=#{state.id}",
Poison.encode!(current_message["message"]),
headers
) do
{:ok, %HTTPoison.Response{status_code: 200, body: _body}} ->
Logger.info("Sended message to hooks-proxy")
timer = Process.send_after(self(), :noresponse, 10 * 1000)
Map.merge(state, %{timer: timer})
{:ok, %HTTPoison.Response{status_code: status, body: _body}} ->
Logger.error("Not found :( reponse status code: #{status}")
timer = Process.send_after(self(), :noresponse, 10 * 1000)
Map.merge(state, %{timer: timer})
{:error, %HTTPoison.Error{reason: reason}} ->
Logger.error("Is not responding reason: #{reason}")
timer = Process.send_after(self(), :noresponse, 10 * 1000)
Map.merge(state, %{timer: timer})
end
end
def handle_info(:noresponse, state) do
Logger.info("NORESPONSE")
[current_message | messages] = state.messages
if state.attempts >= 3 do
Logger.info("FINISH")
# Report status
end_date = NaiveDateTime.utc_now()
resolved_at = Integer.to_string(NaiveDateTime.diff(end_date, state.start, :second))
new_state =
Map.merge(state, %{
end: end_date,
status: "fail",
message: current_message["message"],
resolved_at: resolved_at
})
Logger.error("send to Sentry: #{inspect(new_state.bot)}")
{:stop, :shutdown, state}
else
Logger.error("NO RESPONSE RETRY #{inspect(state.attempts)}")
state = %{state | attempts: state.attempts + 1}
new_state = send_message(current_message, state)
{:noreply, new_state}
end
end
def handle_info(:send_message, state) do
Logger.info("SEND MESSAGE")
[current_message | messages] = state.messages
# enviar mensaje al server con current_activity
new_state = send_message(current_message, state)
{:noreply, new_state}
end
def handle_cast({:recieve_message, recieve_msg}, state) do
recieve_message = Map.delete(recieve_msg, "pid")
Logger.info("RECIEVE MESSAGE #{inspect(recieve_message)}")
if Map.get(state, :timer) != nil do
Logger.info("Cancel timer")
Process.cancel_timer(state.timer)
state = Map.delete(state, "timer")
end
# remove the last message
[head | tail] = state.messages
[current_message | message_queue] = tail
st = %{
bot: state.bot,
messages: message_queue,
start: state.start,
activity: state.activity,
id: state.id,
attempts: state.attempts
}
# verificar si es el mensaje esperado en messages[offset] llega
Logger.info("CURRENT MESSAGE #{inspect(current_message["message"])}")
if message_queue == [] do
if recieve_message == current_message["message"] do
Logger.info("MESSAGE RECIEVE IS THE EXPECTED")
else
Logger.error("MESSAGE RECIEVE IS NOT THE EXPECTED")
end
Logger.info("FINISH")
# Report status
end_date = NaiveDateTime.utc_now()
resolved_at = Integer.to_string(NaiveDateTime.diff(end_date, state.start, :second))
new_state =
Map.merge(state, %{
end: end_date,
status: "ok",
message: "SUCCESS",
resolved_at: resolved_at
})
{:stop, :shutdown, new_state}
else
if recieve_message == current_message["message"] do
Logger.info("MESSAGE RECIEVE IS THE EXPECTED")
[next_message | queue] = message_queue
if next_message["senderType"] == "bot" do
Logger.info("waiting for other message...")
else
Logger.info("Send again....")
st = send_message(next_message, st)
end
else
Logger.error("MESSAGE RECIEVE IS NOT THE EXPECTED")
[next_message | queue] = message_queue
st = send_message(next_message, st)
end
end
{:noreply, st}
end
end