@@ -231,18 +231,29 @@ defmodule ExUnit.CaptureServer do
231
231
## :logger handler callback.
232
232
233
233
def log ( event , _config ) do
234
- for { _ref , string_io , level , formatter_mod , formatter_config } <- :ets . tab2list ( @ ets ) ,
235
- :logger . compare_levels ( event . level , level ) in [ :gt , :eq ] do
236
- chardata = formatter_mod . format ( event , formatter_config )
237
- # There is a race condition where the capture_log is removed
238
- # but another process is attempting to log to string io device
239
- # that no longer exists, so we wrap it in try/catch.
240
- try do
241
- IO . write ( string_io , chardata )
242
- rescue
243
- _ -> :ok
234
+ :ets . tab2list ( @ ets )
235
+ |> Enum . filter ( fn { _ref , _string_io , level , _formatter_mod , _formatter_config } ->
236
+ :logger . compare_levels ( event . level , level ) in [ :gt , :eq ]
237
+ end )
238
+ |> Enum . group_by (
239
+ fn { _ref , _string_io , _level , formatter_mod , formatter_config } ->
240
+ { formatter_mod , formatter_config }
241
+ end ,
242
+ fn { _ref , string_io , _level , _formatter_mod , _formatter_config } ->
243
+ string_io
244
244
end
245
- end
245
+ )
246
+ |> Enum . map ( fn { { formatter_mod , formatter_config } , string_ios } ->
247
+ Task . async ( fn ->
248
+ chardata = formatter_mod . format ( event , formatter_config )
249
+
250
+ # Simply send, do not wait for reply
251
+ for string_io <- string_ios do
252
+ send ( string_io , { :io_request , self ( ) , make_ref ( ) , { :put_chars , :unicode , chardata } } )
253
+ end
254
+ end )
255
+ end )
256
+ |> Task . await_many ( :infinity )
246
257
247
258
:ok
248
259
end
0 commit comments