GenEvent.which_handlers(:error_logger) in Logger.flush/1

81 views
Skip to first unread message

johan.o....@gmail.com

unread,
Jun 2, 2016, 12:54:54 PM6/2/16
to elixir-lang-talk
Hi
I'm reading through the Elixir Logger source code and I'm having trouble to understand the following statment:
_ = GenEvent.which_handlers(:error_logger)

It appears both in the flush method(Line 405) and in add_backend(420) and remove_backend(440)
So I guess that the statement flushes error_logger messages, but I don't understand how or why. Can someone please explain?

I'm also curious if the "_ = ..." part has any effect at all or is it only there to show intent.

Thanks, 
Johan

max s

unread,
Jun 2, 2016, 1:05:53 PM6/2/16
to elixir-l...@googlegroups.com
Hi Johan,

It's a blocking call used to ensure all previous messages have been processed ; hence the flush.

Max

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/7ee66216-8d50-42a1-8ca0-6b2ea7a5faa0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

johan.o....@gmail.com

unread,
Jun 2, 2016, 3:21:49 PM6/2/16
to elixir-lang-talk
Hi Max
Thank you very much for the reply :-)
I still not 100% sure that I understand this correctly:
So would any call() to the error_logger process have the same effect? There is nothing special about the :which_handlers message? Other than it being a call instead of a cast.

johan.o....@gmail.com

unread,
Jun 2, 2016, 4:15:39 PM6/2/16
to elixir-lang-talk
OK, so I figured out that "_=" actually has effect because if I remove _= from line 205 in logger.ex the tests fails.

$ git diff
diff --git a/lib/logger/lib/logger.ex b/lib/logger/lib/logger.ex
index 0ef5ede..644ffcb 100644
--- a/lib/logger/lib/logger.ex
+++ b/lib/logger/lib/logger.ex
@@ -402,7 +402,7 @@ defmodule Logger do
   """
   @spec flush :: :ok
   def flush do
-    _ = GenEvent.which_handlers(:error_logger)
+    GenEvent.which_handlers(:error_logger)
     GenEvent.sync_notify(Logger, :flush)
   end

$ make clean test
......

  1) test drop/2 with negative count stream entries (StreamTest)
     test/elixir/stream_test.exs:202
     No message matching {:stream, 1} after 100ms.
     The process mailbox is empty.
     stacktrace:
       test/elixir/stream_test.exs:215: (test)


Can someone please help me understand?


johan.o....@gmail.com

unread,
Jun 2, 2016, 4:48:48 PM6/2/16
to elixir-lang-talk

This could me my bad: the test failure only occurs sometimes. I guess my computer is to slow :-)

José Valim

unread,
Jun 2, 2016, 4:57:03 PM6/2/16
to elixir-l...@googlegroups.com
The "_ =" is just to signal that the function returns something (in this case handlers) but we are not interested in the result. It does not change the code in any possible way. If the test fails, that's a race condition in the suite and should not be related to your code change.



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

johan.o....@gmail.com

unread,
Jun 2, 2016, 5:24:28 PM6/2/16
to elixir-lang-talk, jose....@plataformatec.com.br
Thank you very much for taking the time to answer my (newbie) question :-)

Another question about the logger.ex: shouldn't add_backend and remove_backend(line 420 and 440) call the flush/1 method instead of GenEvent.which_handlers(:error_logger)

diff --git a/lib/logger/lib/logger.ex b/lib/logger/lib/logger.ex
index 0ef5ede..4feddb9 100644
--- a/lib/logger/lib/logger.ex
+++ b/lib/logger/lib/logger.ex
@@ -417,7 +417,7 @@ defmodule Logger do

   """
   def add_backend(backend, opts \\ []) do
-    _ = if opts[:flush], do: GenEvent.which_handlers(:error_logger)
+    _ = if opts[:flush], do: flush()
     case Logger.Watcher.watch(Logger, Logger.Config.translate_backend(backend), backend) do
       {:ok, _} = ok ->
         Logger.Config.add_backend(backend)
@@ -437,7 +437,7 @@ defmodule Logger do
       the backend is removed
   """
   def remove_backend(backend, opts \\ []) do
-    _ = if opts[:flush], do: GenEvent.which_handlers(:error_logger)
+    _ = if opts[:flush], do: flush()
     Logger.Config.remove_backend(backend)
     Logger.Watcher.unwatch(Logger, Logger.Config.translate_backend(backend))
   end


According to the docs both Logger and Erlang's error_logger message will be flushed if opts[:flush]. And if I understand the code correctly only error_logger messages will be flushed.

/Johan

José Valim

unread,
Jun 2, 2016, 5:42:13 PM6/2/16
to johan.o....@gmail.com, elixir-lang-talk
Yes, it should, specially now that the flush implementation has changed. Can you please send a PR?

Thank you!



José Valim
Skype: jv.ptec
Founder and Director of R&D

johan.o....@gmail.com

unread,
Jun 2, 2016, 6:27:00 PM6/2/16
to elixir-lang-talk, johan.o....@gmail.com, jose....@plataformatec.com.br
I'll be (extremely) happy to make a PR :-)
And thank you!

johan.o....@gmail.com

unread,
Jun 3, 2016, 3:42:29 AM6/3/16
to elixir-lang-talk, johan.o....@gmail.com, jose....@plataformatec.com.br
Hi again

I'm curios about how to make a test for the flush/0 method: To test that it flushes both Logger and error_logger queues. (And similar tests for add_backend and remove_backend given opts[:flush])
I never really liked mocking and expectations but I don't see any other solution. Truth be told, I'm not even sure how to use mocks in Elixir :-)

Is it possible to test if a function call/statement results in a specific message to another processes? 

Or is there a better solution? Or is it just a bad idea to try to test this?

Reply all
Reply to author
Forward
0 new messages