summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-10-02 20:08:01 +0200
committerLinnnus <[email protected]>2024-10-02 20:08:01 +0200
commitc0ff85fd243f0e6cb3f5d4d0d61ad33cc893108f (patch)
tree32e83516ec9c9600d96d014b03d5f6bdb4c07aec
parent6aa23b27b5be52bcc6a27b566cf74cc0bc9c763d (diff)
Expose max-idle-time via NixOS moduleHEADmaster
-rw-r--r--nix/module.nix16
-rw-r--r--nix/test-socket-usage.nix16
-rw-r--r--src/config.rs21
3 files changed, 53 insertions, 0 deletions
diff --git a/nix/module.nix b/nix/module.nix
index 35eba4c..7ef1f98 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -86,6 +86,21 @@ in {
type = types.path;
readOnly = true;
};
+
+ max-idle-time = mkOption {
+ description = ''
+ Maximum time the server should wait for a new connection before exiting.
+
+ In conjunction with socket-activation, this ensures the server isn't
+ using any ressources in the (typically) long periods of time between
+ requests.
+
+ The server will never exit, if this option is set to `null`.
+ '';
+ type = with types; nullOr str;
+ default = null;
+ example = "20min";
+ };
};
};
@@ -131,6 +146,7 @@ in {
config = {
"secret_path" = cfg.secret-path;
"commands" = cfg.commands;
+ "max_idle_time" = cfg.max-idle-time;
};
config-file = pkgs.writers.writeJSON "config.json" config;
diff --git a/nix/test-socket-usage.nix b/nix/test-socket-usage.nix
index 25aa5fc..409dd68 100644
--- a/nix/test-socket-usage.nix
+++ b/nix/test-socket-usage.nix
@@ -1,3 +1,8 @@
+let
+ # Normally the max-idle time would probably be a little longer than this, but
+ # I don't want to drag out this test for 10 minutes.
+ max-idle-secs = 20;
+in
{
name = "socket-usage";
@@ -16,6 +21,8 @@
}
];
+ max-idle-time = "${toString max-idle-secs}s";
+
# The secret to be used when authenticating event's signature.
secret-path = toString (pkgs.writeText "secret.txt" "mysecret");
};
@@ -69,6 +76,8 @@
};
testScript = ''
+ import time
+
machine.start()
with subtest("Proper (lazy) socket activation"):
@@ -87,6 +96,13 @@
exit_code, _ = machine.systemctl("is-active webhook-listener.service --quiet")
assert exit_code == 0, "Event should be active"
+ with subtest("Service should exit after idle time"):
+ # Give it a little buffer to avoid false negatives.
+ time.sleep(${toString max-idle-secs} + 5)
+
+ exit_code, _ = machine.systemctl("is-active webhook-listener.service --quiet")
+ assert exit_code == 3, "Event should be inactive"
+
# TODO: Send an invalid request (subtest).
'';
}
diff --git a/src/config.rs b/src/config.rs
index b929be0..d048586 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -220,4 +220,25 @@ mod tests {
};
assert_eq!(parsed_config, expected_config);
}
+
+ #[test]
+ fn max_idle_time_null_deserializes_to_none() {
+ let config_json = r#"
+ {
+ "secret_path": "/path/to/secret.txt",
+
+ "max_idle_time": null,
+
+ "commands": [ ]
+ }
+ "#;
+ let parsed_config = serde_json::from_str::<Config>(config_json).expect("valid config");
+ let expected_config = Config {
+ secret_path: Path::new("/path/to/secret.txt").to_path_buf(),
+ secret: "".to_string(), // We didn't ask it to read file
+ max_idle_time: None,
+ commands: vec![],
+ };
+ assert_eq!(parsed_config, expected_config);
+ }
}