mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-28 16:07:05 +00:00
Fix notification event stream cleanup, add bounded send concurrency, and reduce overhead (#1224)
This commit is contained in:
@@ -15,13 +15,60 @@
|
||||
use super::rules_map::RulesMap;
|
||||
use super::xml_config::ParseConfigError as BucketNotificationConfigError;
|
||||
use crate::rules::NotificationConfiguration;
|
||||
use crate::rules::pattern_rules;
|
||||
use crate::rules::target_id_set;
|
||||
use hashbrown::HashMap;
|
||||
use crate::rules::subscriber_snapshot::{BucketRulesSnapshot, DynRulesContainer, RuleEvents, RulesContainer};
|
||||
use rustfs_targets::EventName;
|
||||
use rustfs_targets::arn::TargetID;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io::Read;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A "rule view", only used for snapshot mask/consistency verification.
|
||||
/// Here we choose to generate the view by "single event" to ensure that event_mask calculation is reliable and simple.
|
||||
#[derive(Debug)]
|
||||
struct RuleView {
|
||||
events: Vec<EventName>,
|
||||
}
|
||||
|
||||
impl RuleEvents for RuleView {
|
||||
fn subscribed_events(&self) -> &[EventName] {
|
||||
&self.events
|
||||
}
|
||||
}
|
||||
|
||||
/// Adapt RulesMap to RulesContainer.
|
||||
/// Key point: The items returned by iter_rules are &dyn RuleEvents, so a RuleView list is cached in the container.
|
||||
#[derive(Debug)]
|
||||
struct CompiledRules {
|
||||
// Keep RulesMap (can be used later if you want to make more complex judgments during the snapshot reading phase)
|
||||
#[allow(dead_code)]
|
||||
rules_map: RulesMap,
|
||||
// for RulesContainer::iter_rules
|
||||
rule_views: Vec<RuleView>,
|
||||
}
|
||||
|
||||
impl CompiledRules {
|
||||
fn from_rules_map(rules_map: &RulesMap) -> Self {
|
||||
let mut rule_views = Vec::new();
|
||||
|
||||
for ev in rules_map.iter_events() {
|
||||
rule_views.push(RuleView { events: vec![ev] });
|
||||
}
|
||||
|
||||
Self {
|
||||
rules_map: rules_map.clone(),
|
||||
rule_views,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RulesContainer for CompiledRules {
|
||||
type Rule = dyn RuleEvents;
|
||||
|
||||
fn iter_rules<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::Rule> + 'a> {
|
||||
// Key: Convert &RuleView into &dyn RuleEvents
|
||||
Box::new(self.rule_views.iter().map(|v| v as &dyn RuleEvents))
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for bucket notifications.
|
||||
/// This struct now holds the parsed and validated rules in the new RulesMap format.
|
||||
@@ -119,11 +166,26 @@ impl BucketNotificationConfig {
|
||||
pub fn set_region(&mut self, region: &str) {
|
||||
self.region = region.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
// Add a helper to PatternRules if not already present
|
||||
impl pattern_rules::PatternRules {
|
||||
pub fn inner(&self) -> &HashMap<String, target_id_set::TargetIdSet> {
|
||||
&self.rules
|
||||
/// Compiles the current BucketNotificationConfig into a BucketRulesSnapshot.
|
||||
/// This involves transforming the rules into a format suitable for runtime use,
|
||||
/// and calculating the event mask based on the subscribed events of the rules.
|
||||
///
|
||||
/// # Returns
|
||||
/// A BucketRulesSnapshot containing the compiled rules and event mask.
|
||||
pub fn compile_snapshot(&self) -> BucketRulesSnapshot<DynRulesContainer> {
|
||||
// 1) Generate container from RulesMap
|
||||
let compiled = CompiledRules::from_rules_map(self.get_rules_map());
|
||||
let rules: Arc<DynRulesContainer> = Arc::new(compiled) as Arc<DynRulesContainer>;
|
||||
|
||||
// 2) Calculate event_mask
|
||||
let mut mask = 0u64;
|
||||
for rule in rules.iter_rules() {
|
||||
for ev in rule.subscribed_events() {
|
||||
mask |= ev.mask();
|
||||
}
|
||||
}
|
||||
|
||||
BucketRulesSnapshot { event_mask: mask, rules }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user