35 lines
1.2 KiB
C
35 lines
1.2 KiB
C
// A per-service sliding restart budget with explicit count and time window.
|
|
|
|
#pragma once
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#define INIT_RESTART_MAX_ATTEMPTS 16u
|
|
|
|
typedef struct INIT_RESTART_BUDGET {
|
|
uint64_t Attempts[INIT_RESTART_MAX_ATTEMPTS];
|
|
uint32_t Count;
|
|
} INIT_RESTART_BUDGET;
|
|
|
|
static inline bool InitConsumeRestartBudget(INIT_RESTART_BUDGET* budget,
|
|
uint64_t now, uint64_t frequency,
|
|
uint32_t limit, uint32_t windowMilliseconds) {
|
|
if (!budget || !frequency || !limit || limit > INIT_RESTART_MAX_ATTEMPTS ||
|
|
!windowMilliseconds || budget->Count > INIT_RESTART_MAX_ATTEMPTS ||
|
|
frequency > UINT64_MAX / windowMilliseconds)
|
|
return false;
|
|
uint64_t window = frequency * windowMilliseconds;
|
|
window = window / 1000u + (window % 1000u != 0u);
|
|
if (!window) window = 1;
|
|
uint32_t keep = 0;
|
|
for (uint32_t i = 0; i < budget->Count; ++i) {
|
|
uint64_t started = budget->Attempts[i];
|
|
if (now >= started && now - started < window)
|
|
budget->Attempts[keep++] = started;
|
|
}
|
|
budget->Count = keep;
|
|
if (keep >= limit) return false;
|
|
budget->Attempts[budget->Count++] = now;
|
|
return true;
|
|
}
|