-
Notifications
You must be signed in to change notification settings - Fork 121
feat: Add periodic managed host state republishing #2359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2168,6 +2168,12 @@ pub struct DsxExchangeEventBusConfig { | |
|
|
||
| #[serde(default)] | ||
| pub auth: MqttAuthConfig, | ||
|
|
||
| /// Periodically re-publish current `ManagedHostState` in addition to | ||
| /// publishing on every state change. Lets integrators that cannot poll the | ||
| /// NICo API reconcile transitions they missed off the event bus. | ||
| #[serde(default)] | ||
| pub periodic_state_republish: PeriodicStateRepublishConfig, | ||
| } | ||
|
|
||
| impl DsxExchangeEventBusConfig { | ||
|
|
@@ -2184,6 +2190,82 @@ impl DsxExchangeEventBusConfig { | |
| } | ||
| } | ||
|
|
||
| /// Which managed hosts a periodic republish sweep publishes. | ||
| #[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] | ||
| #[serde(rename_all = "snake_case")] | ||
| pub enum RepublishScope { | ||
| /// Republish every managed host on each sweep. Healthy hosts can still be | ||
| /// published less often than unhealthy ones via `healthy_republish_every`. | ||
| #[default] | ||
| All, | ||
| /// Republish only managed hosts that currently have a health alert. Use | ||
| /// this to keep the event bus quiet and only re-advertise hosts that need | ||
| /// attention. | ||
| UnhealthyOnly, | ||
| } | ||
|
|
||
| /// Periodic republishing of `ManagedHostState` on the DSX Exchange Event Bus. | ||
| /// | ||
| /// NICo publishes state on every transition, but integrators that cannot poll | ||
| /// the NICo API (e.g. network-restricted consumers) can miss a transition and | ||
| /// never reconcile. Re-sending current state on a timer lets those consumers | ||
| /// self-heal. Republished messages reuse the same topic and JSON payload as | ||
| /// change-driven events, so consumers handle them identically. | ||
| #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] | ||
| pub struct PeriodicStateRepublishConfig { | ||
| /// Enable periodic republishing. Disabled by default. Change-driven | ||
| /// publishing is unaffected by this setting. | ||
| #[serde(default)] | ||
| pub enabled: bool, | ||
|
|
||
| /// How often a republish sweep runs. Defaults to 5 minutes. | ||
| #[serde( | ||
| default = "PeriodicStateRepublishConfig::default_interval", | ||
| deserialize_with = "deserialize_duration", | ||
| serialize_with = "as_std_duration" | ||
| )] | ||
| pub interval: std::time::Duration, | ||
|
|
||
|
Comment on lines
+2221
to
+2228
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate
Suggested fix pub struct PeriodicStateRepublishConfig {
@@
- pub interval: std::time::Duration,
+ pub interval: std::time::Duration,
@@
}
+
+impl PeriodicStateRepublishConfig {
+ pub fn validate(&self) -> eyre::Result<()> {
+ if self.interval.is_zero() {
+ return Err(eyre::eyre!(
+ "dsx_exchange_event_bus.periodic_state_republish.interval must be > 0s"
+ ));
+ }
+ Ok(())
+ }
+}🤖 Prompt for AI Agents |
||
| /// Which managed hosts to publish on each sweep. | ||
| #[serde(default)] | ||
| pub scope: RepublishScope, | ||
|
|
||
| /// When `scope = all`, publish healthy hosts only every Nth sweep to reduce | ||
| /// broker noise; hosts with an active health alert are always published on | ||
| /// every sweep. `1` (default) publishes healthy hosts every sweep. `0` is | ||
| /// treated as `1`. Ignored when `scope = unhealthy_only`. | ||
| #[serde(default = "PeriodicStateRepublishConfig::default_healthy_republish_every")] | ||
| pub healthy_republish_every: u32, | ||
|
|
||
| /// Upper bound on publishes per second within a single sweep, to avoid | ||
| /// bursting the broker on large sites. `0` (default) disables pacing and | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's have it on by default. also is there stronger typing we can do? any Rate type? |
||
| /// publishes as fast as the broker accepts. | ||
| #[serde(default)] | ||
| pub max_publishes_per_second: u32, | ||
| } | ||
|
|
||
| impl Default for PeriodicStateRepublishConfig { | ||
| fn default() -> Self { | ||
| Self { | ||
| enabled: false, | ||
| interval: Self::default_interval(), | ||
| scope: RepublishScope::default(), | ||
| healthy_republish_every: Self::default_healthy_republish_every(), | ||
| max_publishes_per_second: 0, | ||
| } | ||
|
Comment on lines
+2247
to
+2255
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Default enablement contradicts the stated feature contract.
Suggested fix impl Default for PeriodicStateRepublishConfig {
fn default() -> Self {
Self {
- enabled: false,
+ enabled: true,
interval: Self::default_interval(),
scope: RepublishScope::default(),
healthy_republish_every: Self::default_healthy_republish_every(),
max_publishes_per_second: 0,
}
}
}🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
|
|
||
| impl PeriodicStateRepublishConfig { | ||
| pub const fn default_interval() -> std::time::Duration { | ||
| std::time::Duration::from_secs(300) | ||
| } | ||
|
|
||
| pub const fn default_healthy_republish_every() -> u32 { | ||
| 1 | ||
| } | ||
| } | ||
|
|
||
| /// Auto machine repair plugin related configuration | ||
| #[derive(Default, Clone, Copy, Debug, Deserialize, Serialize)] | ||
| pub struct AutoMachineRepairPluginConfig { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,3 +24,4 @@ | |
|
|
||
| pub mod hook; | ||
| pub mod message; | ||
| pub mod republisher; | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is to be user configurable, you might want to set some
constforminimumandmaximumvalues for this duration. You can thenclamp()to ensure values always fall within the acceptable range.Then just use
Durations::from_secs()