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 delivery that failed
for now leaves the entries in place for the next flush. A batch the server rejected, or one that
failed ForgeOpsTracker.DeliveryStatus.max_failed_flushes/0 flushes in a row, is dropped.
Differences from the Ruby buffers: the buffer is capped at max_entries/0 and drops further
entries once full (an unreachable server fails every flush, and an uncapped buffer would keep
growing until the batch is given up on), 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 lets go of them.
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 lets go of them.
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.