From 98ce341c5fe8403b9dc5654fe18e1ebba61e68e4 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Fri, 12 Dec 2025 10:23:59 -0500 Subject: Publish push messages when a message is sent to a conversation. --- src/test/fixtures/message.rs | 6 +++-- src/test/webpush.rs | 55 ++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 27 deletions(-) (limited to 'src/test') diff --git a/src/test/fixtures/message.rs b/src/test/fixtures/message.rs index 0bd0b7a..39f5963 100644 --- a/src/test/fixtures/message.rs +++ b/src/test/fixtures/message.rs @@ -6,16 +6,18 @@ use crate::{ conversation::Conversation, login::Login, message::{self, Body, Message, app::Messages}, + push::Publish, }; -pub async fn send( +pub async fn send( app: &App, conversation: &Conversation, sender: &Login, sent_at: &RequestedAt, ) -> Message where - Messages: FromRef, + Messages

: FromRef, + P: Publish, { let body = propose(); diff --git a/src/test/webpush.rs b/src/test/webpush.rs index 96fa843..55caf19 100644 --- a/src/test/webpush.rs +++ b/src/test/webpush.rs @@ -2,7 +2,7 @@ use std::{ any::Any, collections::{HashMap, HashSet}, mem, - sync::{Arc, Mutex}, + sync::{Arc, Mutex, MutexGuard}, }; use web_push::{PartialVapidSignatureBuilder, SubscriptionInfo, WebPushError}; @@ -10,59 +10,64 @@ use web_push::{PartialVapidSignatureBuilder, SubscriptionInfo, WebPushError}; use crate::{error::failed::Failed, push::Publish}; #[derive(Clone)] -pub struct Client { - sent: Arc>>, - failures: Arc>>, +pub struct Client(Arc>); + +#[derive(Default)] +struct ClientInner { + sent: Vec, + planned_failures: HashMap, } impl Client { pub fn new() -> Self { - Self { - sent: Arc::default(), - failures: Arc::default(), - } + Self(Arc::default()) + } + + fn inner(&self) -> MutexGuard<'_, ClientInner> { + self.0.lock().unwrap() } // Clears the list of sent messages (for all clones of this Client) when called, because we // can't clone `Publications`s, so we either need to move them or try to reconstruct them. pub fn sent(&self) -> Vec { - let mut sent = self.sent.lock().unwrap(); - mem::take(&mut sent) + let sent = &mut self.inner().sent; + mem::take(sent) } pub fn fail_next(&self, subscription_info: &SubscriptionInfo, err: WebPushError) { - let mut failures = self.failures.lock().unwrap(); - failures.insert(subscription_info.clone(), err); + let planned_failures = &mut self.inner().planned_failures; + planned_failures.insert(subscription_info.clone(), err); } } +#[async_trait::async_trait] impl Publish for Client { - async fn publish( + async fn publish<'s, M>( &self, message: M, - _: PartialVapidSignatureBuilder, - subscriptions: impl IntoIterator + Send, - ) -> Result, Failed> + _: &PartialVapidSignatureBuilder, + subscriptions: impl IntoIterator + Send, + ) -> Result, Failed> where M: Send + 'static, { + let mut inner = self.inner(); let message: Box = Box::new(message); - let subscriptions = subscriptions.into_iter().collect(); + let mut recipients = HashSet::new(); let mut failures = Vec::new(); - - let mut planned_failures = self.failures.lock().unwrap(); - for subscription in &subscriptions { - if let Some(err) = planned_failures.remove(subscription) { - failures.push((subscription.clone(), err)); + for subscription in subscriptions { + recipients.insert(subscription.clone()); + if let Some(err) = inner.planned_failures.remove(subscription) { + failures.push((subscription, err)); } } let publication = Publication { message, - subscriptions, + recipients, }; - self.sent.lock().unwrap().push(publication); + inner.sent.push(publication); Ok(failures) } @@ -71,7 +76,7 @@ impl Publish for Client { #[derive(Debug)] pub struct Publication { pub message: Box, - pub subscriptions: HashSet, + pub recipients: HashSet, } impl Publication { -- cgit v1.2.3