diff options
author | Nick Vatamaniuc <vatamane@gmail.com> | 2022-10-17 13:57:18 -0400 |
---|---|---|
committer | Nick Vatamaniuc <nickva@users.noreply.github.com> | 2022-10-17 16:51:18 -0400 |
commit | 9636405b29f9157eb7870995d837cb53a77cf1f2 (patch) | |
tree | 97585ea67ff98fd2a9e45a65135fa87244649356 | |
parent | e2d88138b0455898a594b1e45b2bdf3a74533203 (diff) | |
download | couchdb-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.erl | 11 |
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). |