feat: add NATS cache sharing and smart cache refresh

Add two complementary features to reduce remote revision cache staleness:

1. Smart local cache: When current system revision matches cached remote
   revision, force an immediate cache refresh to check for newer revisions.

2. NATS integration: Share cache updates across hosts via NATS pub/sub.
   Hosts publish revision updates when they fetch new data, and subscribe
   to receive updates from other hosts. Features include:
   - Auto-reconnect with infinite retries
   - Graceful fallback when NATS unavailable
   - Filtering by flake URL and hostname

New CLI flags:
  --flake.nats.enable
  --flake.nats.url
  --flake.nats.subject
  --flake.nats.credentials-file

New NixOS module options under services.prometheus.exporters.nixos.flake.nats

Bumps version to 0.3.0.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 23:05:52 +01:00
parent cf0ce85899
commit 5cc0e7eadd
7 changed files with 315 additions and 18 deletions

View File

@@ -37,6 +37,28 @@ in
default = "1h";
description = "Interval between remote flake checks.";
};
nats = {
enable = lib.mkEnableOption "NATS cache sharing";
url = lib.mkOption {
type = lib.types.str;
default = "nats://localhost:4222";
description = "NATS server URL.";
};
subject = lib.mkOption {
type = lib.types.str;
default = "nixos-exporter.remote-rev";
description = "NATS subject for revision updates.";
};
credentialsFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Path to NATS credentials file.";
};
};
};
openFirewall = lib.mkOption {
@@ -70,6 +92,10 @@ in
assertion = cfg.flake.enable -> cfg.flake.url != "";
message = "services.prometheus.exporters.nixos.flake.url must be set when flake collector is enabled";
}
{
assertion = cfg.flake.nats.enable -> cfg.flake.enable;
message = "services.prometheus.exporters.nixos.flake.nats.enable requires flake collector to be enabled";
}
];
users.users.${cfg.user} = {
@@ -101,6 +127,12 @@ in
"--collector.flake"
"--flake.url=${cfg.flake.url}"
"--flake.check-interval=${cfg.flake.checkInterval}"
] ++ lib.optionals cfg.flake.nats.enable [
"--flake.nats.enable"
"--flake.nats.url=${cfg.flake.nats.url}"
"--flake.nats.subject=${cfg.flake.nats.subject}"
] ++ lib.optionals (cfg.flake.nats.enable && cfg.flake.nats.credentialsFile != null) [
"--flake.nats.credentials-file=${cfg.flake.nats.credentialsFile}"
]);
Restart = "on-failure";
RestartSec = "5s";