Files
utun2/src/stream/stream_metrics.h
T

66 lines
2.5 KiB
C

/* Относительное отставание одного субпотока от одного поставщика, без NTP и сокетов.
* now_ms — монотонные часы получателя; timestamp — неизменяемые 16-битные часы источника.
* Первый блок/разрыв устанавливает новую базу, история проблем остаётся за последние 60 секунд.
* observe/poll вызываются одним uasync-потоком. DUPLICATE не меняет ни часы, ни статистику. */
#ifndef STREAM_METRICS_H
#define STREAM_METRICS_H
#include "stream_proto.h"
#ifdef __cplusplus
extern "C" {
#endif
#define STREAM_METRIC_SECONDS 60
struct stream_metric_bucket {
uint64_t second;
uint64_t blocks;
uint64_t late_blocks;
uint64_t stops;
uint64_t bytes;
uint64_t source_ms;
uint64_t receive_ms;
uint64_t intervals;
int valid;
};
struct stream_metrics {
struct stream_metric_bucket buckets[STREAM_METRIC_SECONDS];
uint64_t last_seq;
uint64_t last_receive_ms;
uint64_t lag_ms;
uint64_t expected_interval_ms;
uint16_t last_timestamp_ms;
int initialized;
int stopped;
int ended;
};
struct stream_metric_snapshot {
uint64_t lag_ms;
uint64_t blocks;
uint64_t late_blocks;
uint64_t stops;
uint64_t source_rate_bytes_sec;
uint64_t receive_rate_bytes_sec;
uint64_t expected_interval_ms;
uint64_t progress_age_ms; /* Монотонный возраст последнего реально принятого блока; известен при успешном poll. */
int stopped;
int source_rate_valid;
int receive_rate_valid;
};
void stream_metrics_init(struct stream_metrics *metrics);
int stream_metrics_observe(struct stream_metrics *metrics, uint64_t seq, uint16_t timestamp_ms, uint8_t flags,
uint32_t bytes, uint64_t now_ms);
/* Также обнаруживает полную остановку; episode учитывается в момент превышения порога, не на каждом poll.
* До первого блока возвращает WAIT и обнулённый snapshot; при ошибке snapshot остаётся прежним. */
int stream_metrics_poll(struct stream_metrics *metrics, uint64_t now_ms, struct stream_metric_snapshot *snapshot);
void stream_metrics_end(struct stream_metrics *metrics);
#ifdef __cplusplus
}
#endif
#endif