feat(PROJ-56): Last-Entzerrung für OCR und IMAP-Sync
OCR-Worker pausieren optional in konfigurierbarem Zeitfenster (paused_hours), Jobs bleiben pending statt verworfen zu werden. IMAP-Scheduler verteilt Sync-Starts via deterministischem Pro-Account-Jitter, um Lastspitzen bei vielen Postfächern mit gleichem Intervall zu vermeiden. Beides per Config opt-out, Default-Verhalten unverändert. Build + Smoke-Test auf 132 verifiziert.
This commit is contained in:
@@ -54,6 +54,22 @@ imap_server:
|
||||
enabled: false
|
||||
bind: "0.0.0.0:1143"
|
||||
|
||||
# PROJ-56: OCR-Last-Entzerrung (optional).
|
||||
# paused_hours definiert ein lokales Zeitfenster [start, end), in dem der
|
||||
# OCR-Worker NICHT verarbeitet (Aufträge bleiben als pending erhalten).
|
||||
# Wrap-around über Mitternacht wird unterstützt, z.B. [22, 6] = Pause 22:00–06:00.
|
||||
# Ohne Sektion / ohne paused_hours: altes Verhalten (immer aktiv).
|
||||
# ocr:
|
||||
# paused_hours: [8, 18] # OCR pausiert während der Geschäftszeiten
|
||||
|
||||
# PROJ-56: IMAP-Sync-Jitter (optional).
|
||||
# jitter_seconds verteilt den tatsächlichen Sync-Start jedes Accounts
|
||||
# deterministisch (abgeleitet aus Account-ID) über dieses Fenster, damit nicht
|
||||
# alle Postfächer auf derselben Minutengrenze pollen.
|
||||
# Weglassen der Sektion = Default 240s (4 Min). jitter_seconds: 0 = deaktiviert.
|
||||
# imap_scheduler:
|
||||
# jitter_seconds: 240
|
||||
|
||||
audit:
|
||||
log_path: /var/archivmail/audit.log
|
||||
retention_days: 365
|
||||
|
||||
@@ -39,6 +39,47 @@ type Config struct {
|
||||
Logging LoggingConfig `yaml:"logging"`
|
||||
IMAPServer IMAPServerConfig `yaml:"imap_server"`
|
||||
Metrics MetricsConfig `yaml:"metrics"`
|
||||
// PROJ-56: load-spreading for background jobs.
|
||||
OCR OCRConfig `yaml:"ocr"`
|
||||
IMAPScheduler IMAPSchedulerConfig `yaml:"imap_scheduler"`
|
||||
}
|
||||
|
||||
// OCRConfig holds settings for the background OCR worker (PROJ-56).
|
||||
type OCRConfig struct {
|
||||
// PausedHours optionally defines a local-time window [start, end) during
|
||||
// which the OCR worker pauses processing (e.g. [8, 18] = paused 08:00–18:00).
|
||||
// Wrap-around windows are supported, e.g. [22, 6] = paused 22:00–06:00.
|
||||
// nil / unset = never pause (legacy behaviour: process immediately).
|
||||
PausedHours *[2]int `yaml:"paused_hours,omitempty"`
|
||||
}
|
||||
|
||||
// IMAPSchedulerConfig holds settings for the automatic IMAP sync scheduler (PROJ-56).
|
||||
type IMAPSchedulerConfig struct {
|
||||
// JitterSeconds spreads the per-account sync start over a deterministic
|
||||
// offset derived from the account ID, so N accounts on the same interval
|
||||
// don't all poll on the same minute boundary.
|
||||
// A pointer so the unset case (use default) is distinguishable from an
|
||||
// explicit 0 (disable jitter).
|
||||
// nil -> DefaultIMAPJitterSeconds (240s window)
|
||||
// 0 -> jitter disabled (legacy behaviour)
|
||||
// >0 -> jitter window in seconds
|
||||
JitterSeconds *int `yaml:"jitter_seconds,omitempty"`
|
||||
}
|
||||
|
||||
// DefaultIMAPJitterSeconds is the jitter window applied when imap_scheduler
|
||||
// is omitted entirely from the config (4 minutes).
|
||||
const DefaultIMAPJitterSeconds = 240
|
||||
|
||||
// ResolvedJitterSeconds returns the effective jitter window. nil falls back to
|
||||
// the default; an explicit 0 (or negative) means jitter is disabled.
|
||||
func (c IMAPSchedulerConfig) ResolvedJitterSeconds() int {
|
||||
if c.JitterSeconds == nil {
|
||||
return DefaultIMAPJitterSeconds
|
||||
}
|
||||
if *c.JitterSeconds < 0 {
|
||||
return 0
|
||||
}
|
||||
return *c.JitterSeconds
|
||||
}
|
||||
|
||||
// IMAPServerConfig holds settings for the embedded read-only IMAP archive server.
|
||||
|
||||
Reference in New Issue
Block a user