From d1726e9bae65b611ff0b75fac0f79c26f8bdc379 Mon Sep 17 00:00:00 2001 From: Renar Narubin Date: Thu, 21 Sep 2023 13:33:47 -0700 Subject: [PATCH] Support runtime Topic designation Previously the Topic type was only constructible from static strings. This works for code-gen messages, but doesn't work if the topic needs to be determined at runtime. This change permits constructing Topics from arbitrary strings --- Cargo.lock | 10 +++++++++ Cargo.toml | 3 ++- src/backends/googlepubsub/publisher.rs | 23 ++++++++++++-------- src/topic.rs | 29 +++++++++++++++++++------- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95f4838..5030f08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -418,6 +418,7 @@ dependencies = [ "prost", "serde", "serde_json", + "smallstr", "structopt", "thiserror", "tokio", @@ -1276,6 +1277,15 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "smallstr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b1aefdf380735ff8ded0b15f31aab05daf1f70216c01c02a12926badd1df9d" +dependencies = [ + "smallvec", +] + [[package]] name = "smallvec" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index bd20320..caa7adb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hedwig" -version = "6.3.0" +version = "6.4.0" authors = [ "Aniruddha Maru ", "Simonas Kazlauskas ", @@ -39,6 +39,7 @@ bytes = "1" either = { version = "1", features = ["use_std"], default-features = false } futures-util = { version = "0.3.17", features = ["std", "sink"], default-features = false } pin-project = "1" +smallstr = { version = "0.3.0", features = ["union"] } thiserror = { version = "1", default-features = false } url = { version = "2", default-features = false } uuid = { version = "^0.8", features = ["v4"], default-features = false } diff --git a/src/backends/googlepubsub/publisher.rs b/src/backends/googlepubsub/publisher.rs index 9fe03a0..b52010c 100644 --- a/src/backends/googlepubsub/publisher.rs +++ b/src/backends/googlepubsub/publisher.rs @@ -374,16 +374,21 @@ where let sink = { let retry_policy = this.retry_policy; let response_sink = this.response_sink; - this.topic_sinks.entry(topic.clone()).or_insert_with(|| { - Box::pin(TopicSink::new( - client.client.publish_topic_sink( - TopicName::new(topic.as_ref()) - .into_project_topic_name(client.project()), + + // avoid cloning the topic if the key exists + match this.topic_sinks.get_mut(&topic) { + Some(existing) => existing, + None => this.topic_sinks.entry(topic.clone()).or_insert(Box::pin( + TopicSink::new( + client.client.publish_topic_sink( + TopicName::new(topic.as_ref()) + .into_project_topic_name(client.project()), + ), + retry_policy.clone(), + Shared::clone(response_sink), ), - retry_policy.clone(), - Shared::clone(response_sink), - )) - }) + )), + } }; // poll the sink to see if it's ready diff --git a/src/topic.rs b/src/topic.rs index eb88477..e067f1c 100644 --- a/src/topic.rs +++ b/src/topic.rs @@ -1,21 +1,36 @@ +use smallstr::SmallString; + /// A message queue topic name to which messages can be published -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -pub struct Topic(&'static str); +// A survey of common topics found lengths between 16 and 35 bytes +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Topic(SmallString<[u8; 36]>); + +impl Default for Topic { + fn default() -> Self { + Topic(SmallString::new()) + } +} impl std::fmt::Display for Topic { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - std::fmt::Display::fmt(self.0, f) + std::fmt::Display::fmt(self.0.as_str(), f) + } +} + +impl<'a> From<&'a str> for Topic { + fn from(s: &'a str) -> Topic { + Topic(s.into()) } } -impl From<&'static str> for Topic { - fn from(s: &'static str) -> Topic { - Topic(s) +impl From for Topic { + fn from(s: String) -> Topic { + Topic(s.into()) } } impl AsRef for Topic { fn as_ref(&self) -> &str { - self.0 + self.0.as_ref() } }