Collects individual ForgeOpsTracker.capture_metric/2 / capture_infrastructure_metric/3 calls
and periodically flushes them as one batch, rather than one network call per capture. Unlike
ForgeOpsTracker.PerformanceFlusher this keeps a list of individually meaningful entries
instead of summing them into buckets: a customer's own signup or payment is exactly the kind of
thing they will want a genuinely accurate count/sum of later, so the server stores one row per
entry as-is. Ported from gems/forge_ops_tracker's metric_buffer.rb and
infrastructure_metric_buffer.rb, which are the same class twice; here it is one GenServer
started twice under ForgeOpsTracker.Application (:custom and :infrastructure), each
registered under its own name.
Same shape as PerformanceFlusher: a supervised GenServer, a periodic Process.send_after
flush, and a flush in terminate/2 on a normal supervised shutdown (the BEAM equivalent of the
Ruby gem's at_exit, which is what lets a short-lived cron script that captures a few readings
and ends still deliver them, given Process.flag(:trap_exit, true)). Delivery runs synchronously
inside the server, so a record cast that arrives mid-delivery just waits in the mailbox and is
handled right after: nothing recorded during a delivery can be lost, and a failed delivery leaves
the entries in place for the next flush.
Differences from the Ruby buffers: the buffer is capped at max_entries/0 and drops further
entries once full (a plan without the feature answers 403 on every flush, and an uncapped buffer
would then grow for as long as the node lives), and a non-numeric value is dropped at record time
(the BEAM has no NaN or infinity to worry about, but a string would still be an invalid metric).
Summary
Functions
Delivers whatever is buffered right now, without waiting for the next interval.
The most entries one buffer holds; once full, further entries are dropped until a flush succeeds.
The registered name of the buffer for kind.
Adds one entry (everything but recorded_at, which is stamped here). Returns :ok immediately;
a non-numeric value is dropped, and so is anything past max_entries/0.
Types
Functions
@spec flush(kind()) :: :ok
Delivers whatever is buffered right now, without waiting for the next interval.
@spec max_entries() :: pos_integer()
The most entries one buffer holds; once full, further entries are dropped until a flush succeeds.
The registered name of the buffer for kind.
Adds one entry (everything but recorded_at, which is stamped here). Returns :ok immediately;
a non-numeric value is dropped, and so is anything past max_entries/0.