You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2022/10/17 20:51:31 UTC

[couchdb] 01/03: Avoid refresh messages piling up in prometheus server

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 9636405b29f9157eb7870995d837cb53a77cf1f2
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Mon Oct 17 13:57:18 2022 -0400

    Avoid refresh messages piling up in prometheus server
    
    Previously, the cast `refresh` message didn't explicitly cancel the previous
    timer. If a `gen_server:call(Server, refresh)` was made and a `refresh` message
    was already in the message queue, it was possible to end up with two parallel
    refresh periods (cycles): one with the regular refresh period, the other
    generated by the regular refresh gen_server call.
    
    In addition, drain all the previous refresh messages before scheduling a new
    timer. This should further help lower the chance of refresh cycles piling up on
    top of each other.
    
    The fix is mostly theoretical as technically I don't think anything triggers a
    `refresh` gen_server:call/2 calls in practice. It would have to be a manual or
    an externally scripted call.
---
 src/couch_prometheus/src/couch_prometheus_server.erl | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/couch_prometheus/src/couch_prometheus_server.erl b/src/couch_prometheus/src/couch_prometheus_server.erl
index 701483a38..969f68ec9 100644
--- a/src/couch_prometheus/src/couch_prometheus_server.erl
+++ b/src/couch_prometheus/src/couch_prometheus_server.erl
@@ -70,7 +70,8 @@ handle_call(Msg, _From, State) ->
 handle_cast(Msg, State) ->
     {stop, {unknown_cast, Msg}, State}.
 
-handle_info(refresh, State) ->
+handle_info(refresh, #st{refresh = OldRT} = State) ->
+    timer:cancel(OldRT),
     Metrics = refresh_metrics(),
     RT = update_refresh_timer(),
     {noreply, State#st{metrics = Metrics, refresh = RT}};
@@ -184,6 +185,14 @@ get_ets_stats() ->
     NumTabs = length(ets:all()),
     to_prom(erlang_ets_table, gauge, NumTabs).
 
+drain_refresh_messages() ->
+    receive
+        refresh -> drain_refresh_messages()
+    after 0 ->
+        ok
+    end.
+
 update_refresh_timer() ->
+    drain_refresh_messages(),
     RefreshTime = 1000 * config:get_integer("couch_prometheus", "interval", ?REFRESH_INTERVAL),
     erlang:send_after(RefreshTime, self(), refresh).