Skip to content

Commit 73293b9

Browse files
committed
Do not run async groups on load
1 parent 462f614 commit 73293b9

File tree

1 file changed

+53
-57
lines changed

1 file changed

+53
-57
lines changed

lib/ex_unit/lib/ex_unit/server.ex

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ defmodule ExUnit.Server do
5757
state = %{
5858
loaded: System.monotonic_time(),
5959
waiting: nil,
60-
async_groups: %{},
60+
groups: %{},
61+
async_groups: [],
6162
async_modules: :queue.new(),
62-
sync_modules: :queue.new()
63+
sync_modules: []
6364
}
6465

6566
{:ok, state}
@@ -72,31 +73,31 @@ defmodule ExUnit.Server do
7273

7374
# Called once after all async modules have been sent and reverts the state.
7475
def handle_call(:take_sync_modules, _from, state) do
75-
%{waiting: nil, loaded: :done, async_modules: async_modules} = state
76-
0 = :queue.len(async_modules)
76+
%{waiting: nil, loaded: :done, async_groups: []} = state
77+
true = :queue.is_empty(state.async_modules)
7778

78-
{:reply, :queue.to_list(state.sync_modules),
79-
%{state | sync_modules: :queue.new(), loaded: System.monotonic_time()}}
79+
{:reply, state.sync_modules, %{state | sync_modules: [], loaded: System.monotonic_time()}}
8080
end
8181

8282
# Called by the runner when --repeat-until-failure is used.
8383
def handle_call({:restore_modules, async_modules, sync_modules}, _from, state) do
84-
{async_modules, async_groups} =
85-
Enum.map_reduce(async_modules, %{}, fn
86-
{nil, [module]}, {modules, groups} ->
87-
{[{:module, module} | modules], groups}
84+
{async_modules, async_groups, groups} =
85+
Enum.reduce(async_modules, {[], [], []}, fn
86+
{nil, [module]}, {async_modules, async_groups, groups} ->
87+
{[module | async_modules], async_groups, groups}
8888

89-
{group, group_modules}, {modules, groups} ->
90-
{[{:group, group} | modules], Map.put(groups, group, group_modules)}
89+
{group, group_modules}, {async_modules, async_groups, groups} ->
90+
{async_modules, [group | async_groups], [{group, group_modules} | groups]}
9191
end)
9292

9393
{:reply, :ok,
9494
%{
9595
state
9696
| loaded: :done,
97+
groups: Map.new(groups),
9798
async_groups: async_groups,
9899
async_modules: :queue.from_list(async_modules),
99-
sync_modules: :queue.from_list(sync_modules)
100+
sync_modules: sync_modules
100101
}}
101102
end
102103

@@ -108,22 +109,24 @@ defmodule ExUnit.Server do
108109
when is_integer(loaded) do
109110
state =
110111
if uniq? do
111-
async_groups =
112-
Map.new(state.async_groups, fn {group, modules} ->
113-
{group, Enum.uniq(modules)}
114-
end)
115-
112+
groups = Map.new(state.groups, fn {group, modules} -> {group, Enum.uniq(modules)} end)
113+
async_groups = state.async_groups |> Enum.uniq() |> Enum.reverse()
116114
async_modules = :queue.to_list(state.async_modules) |> Enum.uniq() |> :queue.from_list()
117-
sync_modules = :queue.to_list(state.sync_modules) |> Enum.uniq() |> :queue.from_list()
115+
sync_modules = state.sync_modules |> Enum.uniq() |> Enum.reverse()
118116

119117
%{
120118
state
121-
| async_groups: async_groups,
119+
| groups: groups,
120+
async_groups: async_groups,
122121
async_modules: async_modules,
123122
sync_modules: sync_modules
124123
}
125124
else
126-
state
125+
%{
126+
state
127+
| async_groups: Enum.reverse(state.async_groups),
128+
sync_modules: Enum.reverse(state.sync_modules)
129+
}
127130
end
128131

129132
diff = System.convert_time_unit(System.monotonic_time() - loaded, :native, :microsecond)
@@ -132,9 +135,7 @@ defmodule ExUnit.Server do
132135

133136
def handle_call({:add, false = _async, _group, names}, _from, %{loaded: loaded} = state)
134137
when is_integer(loaded) do
135-
state =
136-
update_in(state.sync_modules, &Enum.reduce(names, &1, fn name, q -> :queue.in(name, q) end))
137-
138+
state = update_in(state.sync_modules, &Enum.reverse(names, &1))
138139
{:reply, :ok, state}
139140
end
140141

@@ -143,25 +144,24 @@ defmodule ExUnit.Server do
143144
state =
144145
update_in(
145146
state.async_modules,
146-
&Enum.reduce(names, &1, fn name, q -> :queue.in({:module, name}, q) end)
147+
&Enum.reduce(names, &1, fn name, q -> :queue.in(name, q) end)
147148
)
148149

149150
{:reply, :ok, take_modules(state)}
150151
end
151152

152153
def handle_call({:add, true = _async, group, names}, _from, %{loaded: loaded} = state)
153154
when is_integer(loaded) do
154-
{async_groups, async_modules} =
155-
case state.async_groups do
156-
%{^group => entries} = async_groups ->
157-
{%{async_groups | group => names ++ entries}, state.async_modules}
155+
{groups, async_groups} =
156+
case state.groups do
157+
%{^group => entries} = groups ->
158+
{%{groups | group => Enum.reverse(names, entries)}, state.async_groups}
158159

159-
%{} = async_groups ->
160-
{Map.put(async_groups, group, names), :queue.in({:group, group}, state.async_modules)}
160+
%{} = groups ->
161+
{Map.put(groups, group, names), [group | state.async_groups]}
161162
end
162163

163-
{:reply, :ok,
164-
take_modules(%{state | async_groups: async_groups, async_modules: async_modules})}
164+
{:reply, :ok, take_modules(%{state | groups: groups, async_groups: async_groups})}
165165
end
166166

167167
def handle_call({:add, _async?, _group, _names}, _from, state) do
@@ -174,49 +174,45 @@ defmodule ExUnit.Server do
174174

175175
defp take_modules(%{waiting: {from, count}} = state) do
176176
has_async_modules? = not :queue.is_empty(state.async_modules)
177+
has_async_groups? = state.async_groups != []
177178

178179
cond do
179-
not has_async_modules? and state.loaded == :done ->
180+
not has_async_modules? and not has_async_groups? and state.loaded == :done ->
180181
GenServer.reply(from, nil)
181182
%{state | waiting: nil}
182183

183-
not has_async_modules? ->
184-
state
185-
186-
true ->
187-
{async_modules, remaining_modules} = take_until(count, state.async_modules)
184+
has_async_modules? ->
185+
{reply, remaining_modules} = take_until(count, state.async_modules)
186+
GenServer.reply(from, reply)
187+
%{state | async_modules: remaining_modules, waiting: nil}
188188

189-
{async_modules, remaining_groups} =
190-
Enum.map_reduce(async_modules, state.async_groups, fn
191-
{:module, module}, async_groups ->
192-
{[module], async_groups}
189+
has_async_groups? ->
190+
{groups, remaining_groups} = Enum.split(state.async_groups, count)
193191

194-
{:group, group}, async_groups ->
195-
{group_modules, async_groups} = Map.pop!(async_groups, group)
196-
{Enum.reverse(group_modules), async_groups}
192+
{reply, groups} =
193+
Enum.map_reduce(groups, state.groups, fn group, acc ->
194+
{entries, acc} = Map.pop!(acc, group)
195+
{Enum.reverse(entries), acc}
197196
end)
198197

199-
GenServer.reply(from, async_modules)
198+
GenServer.reply(from, reply)
199+
%{state | groups: groups, async_groups: remaining_groups, waiting: nil}
200200

201-
%{
202-
state
203-
| async_groups: remaining_groups,
204-
async_modules: remaining_modules,
205-
waiting: nil
206-
}
201+
true ->
202+
state
207203
end
208204
end
209205

210-
# :queue.split fails if the provided count is larger than the queue size;
211-
# as we also want to return the values as a list later, we directly
212-
# return {list, queue} instead of {queue, queue}
206+
# :queue.split fails if the provided count is larger than the queue size.
207+
# We also want to return the values as a list of lists, so we directly
208+
# return {list, queue} instead of {queue, queue}.
213209
defp take_until(n, queue), do: take_until(n, queue, [])
214210

215211
defp take_until(0, queue, acc), do: {Enum.reverse(acc), queue}
216212

217213
defp take_until(n, queue, acc) do
218214
case :queue.out(queue) do
219-
{{:value, item}, queue} -> take_until(n - 1, queue, [item | acc])
215+
{{:value, item}, queue} -> take_until(n - 1, queue, [[item] | acc])
220216
{:empty, queue} -> {Enum.reverse(acc), queue}
221217
end
222218
end

0 commit comments

Comments
 (0)