/
receive_message.ex
85 lines (70 loc) · 2.12 KB
/
receive_message.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
defmodule Chaperon.Action.WebSocket.ReceiveMessage do
@moduledoc """
WebSocket action to receive message in a WebSocket-connected session.
"""
defstruct options: [],
decode: nil,
callback: nil
@type t :: %__MODULE__{
options: [any],
callback: Chaperon.Session.result_callback()
}
end
defimpl Chaperon.Actionable, for: Chaperon.Action.WebSocket.ReceiveMessage do
import Chaperon.Timing
import Chaperon.Action.WebSocket.ReceiveMessage
import Chaperon.Session
use Chaperon.Session.Logging
alias Chaperon.Action.WebSocket
def run(action, session) do
{socket, ws_url} =
session
|> WebSocket.for_action(action)
session
|> log_debug("WS_RECV #{ws_url} on socket #{inspect(socket)}")
start = timestamp()
case WebSocket.Client.recv_message(socket, action.options[:timeout]) do
{:binary, message} ->
session
|> log_debug("WS_RECV binary (#{byte_size(message)} bytes)")
|> handle_message(action, message, start)
{:text, message} ->
session
|> log_debug("WS_RECV: #{message}")
|> handle_message(action, message, start)
{:error, {:timeout, timeout}} ->
session
|> log_error("WS_RECV timeout: #{timeout}")
|> run_error_callback(action, {:timeout, timeout})
|> error({:timeout, timeout}, action)
other ->
session
|> log_warn("WS_RECV unexpected message: #{inspect(other)}")
|> ok
end
end
def handle_message(
session,
action,
message,
start_time
) do
{_, ws_url} =
session
|> WebSocket.for_action(action)
dt = timestamp() - start_time
session
|> add_ws_result(action, message)
|> add_metric(:ws_recv, dt)
|> add_metric({:ws_recv, ws_url}, dt)
|> run_callback(action, message)
|> ok
end
def abort(action, session) do
{:ok, action, session}
end
end
defimpl String.Chars, for: Chaperon.Action.WebSocket.ReceiveMessage do
def to_string(%{options: []}), do: "WS-Recv"
def to_string(%{options: opts}), do: "WS-Recv#{inspect(opts)}"
end