summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@gmail.com>2022-10-17 13:57:18 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2022-10-17 16:51:18 -0400
commit9636405b29f9157eb7870995d837cb53a77cf1f2 (patch)
tree97585ea67ff98fd2a9e45a65135fa87244649356
parente2d88138b0455898a594b1e45b2bdf3a74533203 (diff)
downloadcouchdb-9636405b29f9157eb7870995d837cb53a77cf1f2.tar.gz
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.
-rw-r--r--src/couch_prometheus/src/couch_prometheus_server.erl11
1 files changed, 10 insertions, 1 deletions
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).