feat: dynamic user idle_timeout from patch.cfg without container restart

When user.idle_timeout is present in patch.cfg, apply_patch_config() now
updates all active user sessions via usr::update_idle_timeout() and also
updates the cached metric_thresholds array for future connections.

Previously user.idle_timeout was only read at startup (usr::init()) and could
not be changed on a running node without a container restart.

Implementation:
- comm_server.hpp: added for_each_session() template to iterate live sessions
  (shared with feat/dynamic-mesh-idle-timeout-from-patch-cfg)
- usr.cpp: added update_idle_timeout() which updates metric_thresholds[4] and
  calls set_threshold(IDLE_CONNECTION_TIMEOUT) on all active user sessions
- conf.cpp: reads user.idle_timeout from patch.cfg in apply_patch_config(),
  calls usr::update_idle_timeout() when value changes

Sibling PRs (part of dynamic config series):
- fix/dynamic-log-level-from-patch-cfg (already raised)
- feat/dynamic-mesh-idle-timeout-from-patch-cfg (already raised)
This commit is contained in:
rippleitinnz
2026-05-21 09:39:16 +12:00
parent 1117dda575
commit a770ff3a03
2 changed files with 36 additions and 0 deletions

View File

@@ -7,6 +7,9 @@
#include "ledger/ledger_mount.hpp"
#include "sc/contract_mount.hpp"
// Forward declaration to avoid circular dependency with usr/usr.hpp
namespace usr { void update_idle_timeout(const uint32_t timeout_ms); }
namespace conf
{
@@ -853,6 +856,21 @@ namespace conf
return -1;
}
// Apply user idle timeout change dynamically if present in patch config.
// Updates all active user sessions and future connections without restart.
try {
if (jdoc.contains("user") && jdoc["user"].contains("idle_timeout")) {
const uint32_t new_idle_timeout = jdoc["user"]["idle_timeout"].as<uint32_t>();
if (new_idle_timeout != cfg.user.idle_timeout) {
cfg.user.idle_timeout = new_idle_timeout;
temp_cfg.user.idle_timeout = new_idle_timeout;
usr::update_idle_timeout(new_idle_timeout);
LOG_INFO << "User idle timeout updated dynamically to: " << new_idle_timeout << "ms";
}
}
} catch (const std::exception &e) {
LOG_ERROR << "Error applying user idle timeout from patch config: " << e.what();
}
LOG_INFO << "Contract config updated from patch file.";
return 0;
}

View File

@@ -74,6 +74,24 @@ namespace usr
}
}
/**
* Update user idle timeout on all active user sessions and for future connections.
* Called from conf::apply_patch_config() when user.idle_timeout changes in patch.cfg.
* Updates both the cached metric_thresholds array (for new sessions) and all
* existing live sessions via set_threshold() so no restart is required.
*/
void update_idle_timeout(const uint32_t timeout_ms)
{
metric_thresholds[4] = timeout_ms;
if (ctx.server.has_value())
{
ctx.server->for_each_session([timeout_ms](user_comm_session &session) {
session.set_threshold(comm::SESSION_THRESHOLDS::IDLE_CONNECTION_TIMEOUT, timeout_ms, 60000);
});
LOG_INFO << "User idle timeout updated dynamically to: " << timeout_ms << "ms";
}
}
/**
* Starts listening for incoming user websocket connections.
*/