-
Notifications
You must be signed in to change notification settings - Fork 23
/
responders.ex
134 lines (110 loc) · 3.5 KB
/
responders.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
defmodule ExActor.Responders do
@moduledoc """
Helper macros that can be used for simpler responses from init/call/cast/info
handlers.
"""
@doc """
Sets the initial state.
Applicable in:
- `ExActor.Operations.defstart/3`
- `ExActor.Operations.definit/2`
"""
defmacro initial_state(state, timeout \\ nil) do
timeout = timeout || quote(do: Process.get(ExActor.ResponseDecoration) || :infinity)
quote do
{:ok, unquote(state), unquote(timeout)}
end
end
@doc """
Ensures that timeout will be included in each return tuple.
Must be called from `ExActor.Operations.defstart/2` (or `definit`).
This works only for return tuples made by macros from this module. If you're
creating standard `gen_server` response manually, it's your responsibility to
include the timeout, or override it if you want to.
"""
defmacro timeout_after(time_ms) do
quote do
Process.put(ExActor.ResponseDecoration, unquote(time_ms))
end
end
@doc """
Ensures that `:hibernate` will be included in each return tuple.
Must be called from `ExActor.Operations.defstart/2` (or `definit`).
This works only for return tuples made by macros from this module. If you're
creating standard `gen_server` response manually, it's your responsibility to
include the `:hibernate`, or override it if you want to.
"""
defmacro hibernate do
quote do
Process.put(ExActor.ResponseDecoration, :hibernate)
end
end
@doc """
Replies without changing the state.
Applicable in:
- `ExActor.Operations.defcall/3`
- `ExActor.Operations.defmulticall/3`
"""
defmacro reply(response, timeout \\ nil) do
timeout = timeout || quote(do: Process.get(ExActor.ResponseDecoration) || :infinity)
quote do
{:reply, unquote(response), unquote(ExActor.Helper.state_var), unquote(timeout)}
end
end
@doc """
Replies and sets the new state
Applicable in:
- `ExActor.Operations.defcall/3`
- `ExActor.Operations.defmulticall/3`
"""
defmacro set_and_reply(new_state, response, timeout \\ nil) do
timeout = timeout || quote(do: Process.get(ExActor.ResponseDecoration) || :infinity)
quote do
{:reply, unquote(response), unquote(new_state), unquote(timeout)}
end
end
@doc """
Sets the new state.
Applicable in:
- `ExActor.Operations.defcall/3`
- `ExActor.Operations.defcast/3`
- `ExActor.Operations.defabcast/3`
- `ExActor.Operations.defmulticall/3`
- `ExActor.Operations.defhandleinfo/3`
"""
defmacro new_state(state, timeout \\ nil) do
timeout = timeout || quote(do: Process.get(ExActor.ResponseDecoration) || :infinity)
quote do
{:noreply, unquote(state), unquote(timeout)}
end
end
@doc """
Leaves the state unchanged.
Applicable in:
- `ExActor.Operations.defcall/3`
- `ExActor.Operations.defcast/3`
- `ExActor.Operations.defabcast/3`
- `ExActor.Operations.defmulticall/3`
- `ExActor.Operations.defhandleinfo/3`
"""
defmacro noreply(timeout \\ nil) do
timeout = timeout || quote(do: Process.get(ExActor.ResponseDecoration) || :infinity)
quote do
{:noreply, unquote(ExActor.Helper.state_var), unquote(timeout)}
end
end
@doc """
Stops the server.
Applicable in:
- `ExActor.Operations.defcall/3`
- `ExActor.Operations.defcast/3`
- `ExActor.Operations.defabcast/3`
- `ExActor.Operations.defmulticall/3`
- `ExActor.Operations.defhandleinfo/3`
"""
defmacro stop_server(reason) do
quote do
{:stop, unquote(reason), unquote(ExActor.Helper.state_var)}
end
end
end