Skip to content

Commit b7ce2a7

Browse files
committed
Replace message worker/sup with poolboy worker pool
1 parent 2c665dd commit b7ce2a7

File tree

6 files changed

+107
-167
lines changed

6 files changed

+107
-167
lines changed

lib/gmail/message/pool.ex

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
defmodule Gmail.Message.Pool do
2+
3+
@moduledoc """
4+
A pool of workers for handling message operations.
5+
"""
6+
7+
alias Gmail.Message.PoolWorker
8+
9+
@default_pool_size 20
10+
11+
@doc false
12+
def start_link do
13+
poolboy_config = [
14+
{:name, {:local, :message_pool}},
15+
{:worker_module, PoolWorker},
16+
{:size, pool_size},
17+
{:max_overflow, 0}
18+
]
19+
20+
children = [
21+
:poolboy.child_spec(:message_pool, poolboy_config, [])
22+
]
23+
24+
options = [
25+
strategy: :one_for_one,
26+
name: __MODULE__
27+
]
28+
29+
Supervisor.start_link(children, options)
30+
end
31+
32+
@doc """
33+
Gets a message.
34+
"""
35+
@spec get(String.t, String.t, map, map) :: {atom, map}
36+
def get(user_id, message_id, params, state) do
37+
:poolboy.transaction(
38+
:message_pool,
39+
fn pid ->
40+
PoolWorker.get(pid, user_id, message_id, params, state)
41+
end,
42+
:infinity)
43+
end
44+
45+
def pool_size do
46+
case Application.get_env(:gmail, :message) do
47+
[pool: size] when is_integer(size) ->
48+
size
49+
_ ->
50+
@default_pool_size
51+
end
52+
end
53+
54+
end

lib/gmail/message/pool_worker.ex

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
defmodule Gmail.Message.PoolWorker do
2+
3+
@moduledoc """
4+
A message pool worker.
5+
"""
6+
7+
use GenServer
8+
alias Gmail.{Message, User}
9+
10+
@doc false
11+
def start_link([]) do
12+
GenServer.start_link(__MODULE__, [], [])
13+
end
14+
15+
@doc false
16+
def init(state) do
17+
{:ok, state}
18+
end
19+
20+
@doc false
21+
def handle_call({:get, user_id, message_id, params, state}, _from, worker_state) do
22+
result =
23+
user_id
24+
|> Message.get(message_id, params)
25+
|> User.http_execute(state)
26+
|> Message.handle_message_response
27+
{:reply, result, worker_state}
28+
end
29+
30+
@doc """
31+
Gets a message.
32+
"""
33+
@spec get(pid, String.t, String.t, map, map) :: {atom, map}
34+
def get(pid, user_id, message_id, params, state) do
35+
GenServer.call(pid, {:get, user_id, message_id, params, state}, :infinity)
36+
end
37+
38+
end
39+

lib/gmail/message/supervisor.ex

Lines changed: 0 additions & 22 deletions
This file was deleted.

lib/gmail/message/worker.ex

Lines changed: 0 additions & 139 deletions
This file was deleted.

lib/gmail/supervisor.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ defmodule Gmail.Supervisor do
1616
children = [
1717
supervisor(Gmail.UserManager, []),
1818
supervisor(Gmail.Thread.Pool, []),
19-
supervisor(Gmail.Message.Supervisor, [])
19+
supervisor(Gmail.Message.Pool, [])
2020
]
2121
supervise(children, strategy: :one_for_one)
2222
end

lib/gmail/user.ex

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,22 @@ defmodule Gmail.User do
148148
end
149149

150150
@doc false
151-
def handle_call({:message, {:get, message_ids, params}}, from, state) when is_list(message_ids) do
152-
Gmail.Message.Worker.fetch(from, message_ids, params, state)
153-
{:noreply, state}
151+
def handle_call({:message, {:get, message_ids, params}}, _from, %{user_id: user_id} = state) when is_list(message_ids) do
152+
messages =
153+
message_ids
154+
|> Enum.map(fn id ->
155+
Task.async(fn ->
156+
{:ok, message} = Gmail.Message.Pool.get(user_id, id, params, state)
157+
message
158+
end)
159+
end)
160+
|> Enum.map(fn task -> Task.await(task, :infinity) end)
161+
{:reply, {:ok, messages}, state}
154162
end
155163

156164
@doc false
157-
def handle_call({:message, {:get, message_id, params}}, _from, state) do
158-
result = Gmail.Message.Worker.get(message_id, params, state);
165+
def handle_call({:message, {:get, message_id, params}}, _from, %{user_id: user_id} = state) do
166+
result = Gmail.Message.Pool.get(user_id, message_id, params, state)
159167
{:reply, result, state}
160168
end
161169

0 commit comments

Comments
 (0)