commit 0e9665c9de7fdceadcbbdc4d9652bf7326876dcf
parent f7f3c57a8e590017ae925464188b944b37e4fa28
Author: kernelkind <kernelkind@gmail.com>
Date: Thu, 5 Feb 2026 16:07:20 -0500
feat(outbox): add `QueuedTasks`
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/crates/enostr/src/relay/mod.rs b/crates/enostr/src/relay/mod.rs
@@ -4,6 +4,7 @@ mod limits;
pub mod message;
mod multicast;
pub mod pool;
+mod queue;
pub mod subs_debug;
mod websocket;
@@ -16,6 +17,7 @@ pub use limits::{
};
pub use multicast::{MulticastRelay, MulticastRelayCache};
use nostrdb::Filter;
+pub use queue::QueuedTasks;
pub use websocket::{WebsocketConn, WebsocketRelay};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
diff --git a/crates/enostr/src/relay/queue.rs b/crates/enostr/src/relay/queue.rs
@@ -0,0 +1,47 @@
+use std::collections::{btree_set, BTreeSet};
+
+use crate::relay::{OutboxSubId, RelayTask};
+
+/// QueuedTasks stores subscription work that could not be scheduled immediately.
+#[derive(Default)]
+pub struct QueuedTasks {
+ tasks: BTreeSet<OutboxSubId>,
+}
+
+impl QueuedTasks {
+ pub fn add(&mut self, id: OutboxSubId, task: RelayTask) {
+ match task {
+ RelayTask::Unsubscribe => {
+ // i guess swap remove is ok here? it's not super important to maintain strict insertion order
+ if !self.tasks.contains(&id) {
+ return;
+ }
+ self.tasks.remove(&id);
+ }
+ RelayTask::Subscribe => {
+ self.tasks.insert(id);
+ }
+ }
+ }
+
+ pub fn pop(&mut self) -> Option<OutboxSubId> {
+ self.tasks.pop_last()
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.tasks.is_empty()
+ }
+
+ pub fn len(&self) -> usize {
+ self.tasks.len()
+ }
+}
+
+impl IntoIterator for QueuedTasks {
+ type Item = OutboxSubId;
+ type IntoIter = btree_set::IntoIter<OutboxSubId>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.tasks.into_iter()
+ }
+}