Merge pull request #151 from basho/adt-disable-date-rotation

Can't disable periodic file rotation
diff --git a/README.md b/README.md
index 7c00447..116be24 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,6 @@
     {lager_console_backend, info},
     {lager_file_backend, [{file, "error.log"}, {level, error}]},
     {lager_file_backend, [{file, "console.log"}, {level, info}]}
-    ]}
   ]}
 ]}.
 ```
@@ -102,7 +101,6 @@
     {lager_file_backend, [{name, "error.log"}, {level, error}, {formatter, lager_default_formatter},
       {formatter_config, [date, " ", time," [",severity,"] ",pid, " ", message, "\n"]}]},
     {lager_file_backend, [{name, "console.log"}, {level, info}]}
-    ]}
   ]}
 ]}.
 ```
@@ -154,11 +152,13 @@
 asynchronous depending on mailbox size.
 
 ```erlang
-{async_threshold, 20}
+{async_threshold, 20},
+{async_threshold_window, 5}
 ```
 
 This will use async messaging until the mailbox exceeds 20 messages, at which
-point synchronous messaging will be used.
+point synchronous messaging will be used, and switch back to asynchronous, when
+size reduces to `20 - 5 = 15`.
 
 If you wish to disable this behaviour, simply set it to 'undefined'. It defaults
 to a low number to prevent the mailbox growing rapidly beyond the limit and causing
diff --git a/src/lager.app.src b/src/lager.app.src
index 5c88a0b..63f35ce 100644
--- a/src/lager.app.src
+++ b/src/lager.app.src
@@ -53,6 +53,9 @@
             %% How many messages per second to allow from error_logger before we start dropping them
             {error_logger_hwm, 50},
             %% How big the gen_event mailbox can get before it is switched into sync mode
-            {async_threshold, 20}
+            {async_threshold, 20},
+            %% Switch back to async mode, when gen_event mailbox size decrease from `async_threshold'
+            %% to async_threshold - async_threshold_window
+            {async_threshold_window, 5}
         ]}
  ]}.
diff --git a/src/lager_app.erl b/src/lager_app.erl
index 148742f..d169f80 100644
--- a/src/lager_app.erl
+++ b/src/lager_app.erl
@@ -42,7 +42,20 @@
         {ok, undefined} ->
             undefined;
         {ok, Threshold} when is_integer(Threshold), Threshold >= 0 ->
-            _ = supervisor:start_child(lager_handler_watcher_sup, [lager_event, lager_backend_throttle, Threshold]),
+            DefWindow = erlang:trunc(Threshold * 0.2), % maybe 0?
+            ThresholdWindow =
+                case application:get_env(lager, async_threshold_window) of
+                    undefined ->
+                        DefWindow;
+                    {ok, Window} when is_integer(Window), Window < Threshold, Window >= 0 ->
+                        Window;
+                    {ok, BadWindow} ->
+                        error_logger:error_msg(
+                          "Invalid value for 'async_threshold_window': ~p~n", [BadWindow]),
+                        throw({error, bad_config})
+                end,
+            _ = supervisor:start_child(lager_handler_watcher_sup,
+                                       [lager_event, lager_backend_throttle, [Threshold, ThresholdWindow]]),
             ok;
         {ok, BadThreshold} ->
             error_logger:error_msg("Invalid value for 'async_threshold': ~p~n", [BadThreshold]),
diff --git a/src/lager_backend_throttle.erl b/src/lager_backend_throttle.erl
index 34ff46e..14573b0 100644
--- a/src/lager_backend_throttle.erl
+++ b/src/lager_backend_throttle.erl
@@ -31,12 +31,13 @@
 
 -record(state, {
         hwm,
+        window_min,
         async = true
     }).
 
-init(Hwm) ->
+init([Hwm, Window]) ->
     lager_config:set(async, true),
-    {ok, #state{hwm=Hwm}}.
+    {ok, #state{hwm=Hwm, window_min=Hwm - Window}}.
 
 
 handle_call(get_loglevel, State) ->
@@ -48,12 +49,12 @@
 
 handle_event({log, _Message},State) ->
     {message_queue_len, Len} = erlang:process_info(self(), message_queue_len),
-    case {Len > State#state.hwm, State#state.async} of
-        {true, true} ->
+    case {Len > State#state.hwm, Len < State#state.window_min, State#state.async} of
+        {true, _, true} ->
             %% need to flip to sync mode
             lager_config:set(async, false),
             {ok, State#state{async=false}};
-        {false, false} ->
+        {_, true, false} ->
             %% need to flip to async mode
             lager_config:set(async, true),
             {ok, State#state{async=true}};