mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-07 02:51:41 +00:00
perf(engine): keep each events.poll topic once (#1935)
The topic list was validated but not deduplicated, and it is scanned for every retained event while the log's lock is held, so a request repeating one topic thousands of times multiplied that work. Repeats collapse and a list naming all is just all.
This commit is contained in:
1 parent
df07ac2d09
commit
417ad412a2
2 files changed
+9
-2
No files matched your search
@@ -127,12 +127,15 @@ pub fn topics(v: Option<&Value>) -> Result<Vec<String>, String> {
|
||||
for t in list {
|
||||
let Some(s) = t.as_str() else { return Err("`topics` must be an array of strings".into()) };
|
||||
match s {
|
||||
// Each once: the list is scanned for every retained event under the log's lock, so
|
||||
// a long list of repeats would multiply that work.
|
||||
"comments" | "document" | "all" if out.iter().any(|t| t == s) => {}
|
||||
"comments" | "document" | "all" => out.push(s.to_string()),
|
||||
other => return Err(format!("unknown topic `{other}` (comments, document, all)")),
|
||||
}
|
||||
}
|
||||
if out.is_empty() {
|
||||
out.push("all".into());
|
||||
if out.is_empty() || out.iter().any(|t| t == "all") {
|
||||
out = vec!["all".into()];
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
@@ -193,6 +193,10 @@ fn topics_parse_and_reject_unknown_names() {
|
||||
assert_eq!(events::topics(Some(&json!([]))).unwrap(), vec!["all".to_string()]);
|
||||
assert_eq!(events::topics(Some(&json!(["comments", "document"]))).unwrap(), vec!["comments".to_string(), "document".to_string()]);
|
||||
assert!(events::topics(Some(&json!(["nope"]))).is_err());
|
||||
// Repeats collapse (the list is scanned per event under the log's lock), and `all` is all.
|
||||
let many: Vec<&str> = std::iter::repeat_n("comments", 10_000).chain(["document"]).collect();
|
||||
assert_eq!(events::topics(Some(&json!(many))).unwrap(), vec!["comments".to_string(), "document".to_string()]);
|
||||
assert_eq!(events::topics(Some(&json!(["comments", "all", "document"]))).unwrap(), vec!["all".to_string()]);
|
||||
assert!(events::topics(Some(&json!("comments"))).is_err());
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user