1use std::sync::{Arc, Mutex};
24use std::task::{self, Poll};
25
26use tower_service::Service;
27
28use self::internal::{SingletonError, SingletonFuture, State};
29
30type BoxError = Box<dyn std::error::Error + Send + Sync>;
31
32#[cfg(docsrs)]
33pub use self::internal::Singled;
34
35#[derive(Debug)]
41pub struct Singleton<M, Dst>
42where
43 M: Service<Dst>,
44{
45 mk_svc: M,
46 state: Arc<Mutex<State<M::Future, M::Response>>>,
47}
48
49impl<M, Target> Singleton<M, Target>
50where
51 M: Service<Target>,
52 M::Response: Clone,
53{
54 pub fn new(mk_svc: M) -> Self {
56 Singleton {
57 mk_svc,
58 state: Arc::new(Mutex::new(State::Empty)),
59 }
60 }
61
62 pub fn retain<F>(&mut self, mut predicate: F)
66 where
67 F: FnMut(&mut M::Response) -> bool,
68 {
69 let mut locked = self.state.lock().unwrap();
70 match *locked {
71 State::Empty => {}
72 State::Making(..) => {}
73 State::Made(ref mut svc) => {
74 if !predicate(svc) {
75 *locked = State::Empty;
76 }
77 }
78 }
79 }
80
81 pub fn is_empty(&self) -> bool {
86 matches!(*self.state.lock().unwrap(), State::Empty)
87 }
88}
89
90impl<M, Target> Service<Target> for Singleton<M, Target>
91where
92 M: Service<Target>,
93 M::Response: Clone,
94 M::Error: Into<BoxError>,
95{
96 type Response = internal::Singled<M::Future, M::Response>;
97 type Error = SingletonError;
98 type Future = SingletonFuture<M::Future, M::Response>;
99
100 fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
101 if let State::Empty = *self.state.lock().unwrap() {
102 return self
103 .mk_svc
104 .poll_ready(cx)
105 .map_err(|e| SingletonError::new(e.into()));
106 }
107 Poll::Ready(Ok(()))
108 }
109
110 fn call(&mut self, dst: Target) -> Self::Future {
111 let mut locked = self.state.lock().unwrap();
112 match *locked {
113 State::Empty => {
114 let fut = self.mk_svc.call(dst);
115 let mut batch = internal::Batch::new(fut);
116 let id = batch.register_driver();
117 *locked = State::Making(batch);
118 SingletonFuture::Participating {
119 id,
120 state: self.state.clone(),
121 rx: None,
122 }
123 }
124 State::Making(ref mut batch) => {
125 let (id, rx) = batch.register_waiter();
126 SingletonFuture::Participating {
127 id,
128 state: self.state.clone(),
129 rx: Some(rx),
130 }
131 }
132 State::Made(ref svc) => SingletonFuture::Made {
133 svc: Some(svc.clone()),
134 state: Arc::downgrade(&self.state),
135 },
136 }
137 }
138}
139
140impl<M, Target> Clone for Singleton<M, Target>
141where
142 M: Service<Target> + Clone,
143{
144 fn clone(&self) -> Self {
145 Self {
146 mk_svc: self.mk_svc.clone(),
147 state: self.state.clone(),
148 }
149 }
150}
151
152mod internal {
161 use std::fmt;
162 use std::pin::Pin;
163 use std::sync::{Arc, Mutex, Weak};
164 use std::task::{self, Poll, Waker};
165
166 use tokio::sync::oneshot;
167 use tower_service::Service;
168
169 use super::BoxError;
170
171 pub enum SingletonFuture<F, S> {
172 Participating {
173 id: WaiterId,
174 state: Arc<Mutex<State<F, S>>>,
175 rx: Option<oneshot::Receiver<Result<S, SharedError>>>,
176 },
177 Made {
178 svc: Option<S>,
179 state: Weak<Mutex<State<F, S>>>,
180 },
181 }
182
183 impl<F, S> Unpin for SingletonFuture<F, S> {}
184
185 pub enum State<F, S> {
187 Empty,
188 Making(Batch<F, S>),
189 Made(S),
190 }
191
192 impl<F, S: fmt::Debug> fmt::Debug for State<F, S> {
193 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194 match self {
195 State::Empty => f.write_str("Empty"),
196 State::Making(..) => f.write_str("Making"),
197 State::Made(svc) => f.debug_tuple("Made").field(svc).finish(),
198 }
199 }
200 }
201
202 pub struct Batch<F, S> {
204 future: Option<Pin<Box<F>>>,
205 next_id: WaiterId,
206 driver: Option<Driver>,
207 waiters: Vec<Waiter<S>>,
208 }
209
210 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
211 pub struct WaiterId(usize);
212
213 struct Driver {
214 id: WaiterId,
215 waker: Option<Waker>,
216 }
217
218 struct Waiter<S> {
219 id: WaiterId,
220 waker: Option<Waker>,
221 tx: oneshot::Sender<Result<S, SharedError>>,
222 }
223
224 #[derive(Debug)]
238 pub struct Singled<F, S> {
239 inner: S,
240 state: Weak<Mutex<State<F, S>>>,
241 }
242
243 impl<F, S, E> Future for SingletonFuture<F, S>
244 where
245 F: Future<Output = Result<S, E>>,
246 E: Into<BoxError>,
247 S: Clone,
248 {
249 type Output = Result<Singled<F, S>, SingletonError>;
250
251 fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
252 match &mut *self {
253 SingletonFuture::Participating { id, state, rx } => {
254 if let Some(receiver) = rx.as_mut() {
255 match Pin::new(receiver).poll(cx) {
256 Poll::Ready(Ok(Ok(svc))) => {
257 return Poll::Ready(Ok(Singled::new(svc, Arc::downgrade(state))));
258 }
259 Poll::Ready(Ok(Err(err))) => {
260 return Poll::Ready(Err(SingletonError(err)));
261 }
262 Poll::Ready(Err(_canceled)) => {
263 *rx = None;
264 }
265 Poll::Pending => {}
266 }
267 }
268
269 let state_weak = Arc::downgrade(state);
270 let mut locked = state.lock().unwrap();
271
272 match &mut *locked {
273 State::Making(batch) => match batch.poll(*id, cx) {
274 Poll::Pending => Poll::Pending,
275 Poll::Ready(Ok(svc)) => {
276 batch.send_result(Ok(svc.clone()));
277 *locked = State::Made(svc.clone());
278 Poll::Ready(Ok(Singled::new(svc, state_weak)))
279 }
280 Poll::Ready(Err(err)) => {
281 batch.send_result(Err(err.clone()));
282 *locked = State::Empty;
283 Poll::Ready(Err(SingletonError(err)))
284 }
285 },
286 State::Made(svc) => Poll::Ready(Ok(Singled::new(svc.clone(), state_weak))),
287 State::Empty => {
288 unreachable!("singleton participant polled after making was canceled")
289 }
290 }
291 }
292 SingletonFuture::Made { svc, state } => {
293 Poll::Ready(Ok(Singled::new(svc.take().unwrap(), state.clone())))
294 }
295 }
296 }
297 }
298
299 impl<F, S> Drop for SingletonFuture<F, S> {
300 fn drop(&mut self) {
301 if let SingletonFuture::Participating { id, state, .. } = self {
302 if let Ok(mut locked) = state.lock() {
303 if let State::Making(batch) = &mut *locked {
304 if batch.remove(*id) {
305 *locked = State::Empty;
306 }
307 }
308 }
309 }
310 }
311 }
312
313 impl<F, S> Singled<F, S> {
314 fn new(inner: S, state: Weak<Mutex<State<F, S>>>) -> Self {
315 Singled { inner, state }
316 }
317 }
318
319 impl<F, S, Req> Service<Req> for Singled<F, S>
320 where
321 S: Service<Req>,
322 {
323 type Response = S::Response;
324 type Error = S::Error;
325 type Future = S::Future;
326
327 fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
328 match self.inner.poll_ready(cx) {
330 Poll::Ready(Err(err)) => {
331 if let Some(state) = self.state.upgrade() {
332 *state.lock().unwrap() = State::Empty;
333 }
334 Poll::Ready(Err(err))
335 }
336 other => other,
337 }
338 }
339
340 fn call(&mut self, req: Req) -> Self::Future {
341 self.inner.call(req)
342 }
343 }
344
345 impl<F, S> Batch<F, S> {
346 pub(super) fn new(future: F) -> Self {
347 Batch {
348 future: Some(Box::pin(future)),
349 next_id: WaiterId(0),
350 driver: None,
351 waiters: Vec::new(),
352 }
353 }
354
355 pub(super) fn register_driver(&mut self) -> WaiterId {
356 let id = self.next_id;
357 self.next_id.0 += 1;
358 self.driver = Some(Driver { id, waker: None });
359 id
360 }
361
362 pub(super) fn register_waiter(
363 &mut self,
364 ) -> (WaiterId, oneshot::Receiver<Result<S, SharedError>>) {
365 let id = self.next_id;
366 self.next_id.0 += 1;
367 let (tx, rx) = oneshot::channel();
368 self.waiters.push(Waiter {
369 id,
370 waker: None,
371 tx,
372 });
373 (id, rx)
374 }
375
376 fn remove(&mut self, id: WaiterId) -> bool {
377 if let Some(pos) = self.waiters.iter().position(|waiter| waiter.id == id) {
378 self.waiters.swap_remove(pos);
379 return false;
380 }
381
382 if self.driver.as_ref().is_some_and(|driver| driver.id == id) {
383 if let Some(waiter) = self.waiters.pop() {
384 let waker = waiter.waker;
385 self.driver = Some(Driver {
386 id: waiter.id,
387 waker,
388 });
389 self.wake_driver();
390 return false;
391 }
392
393 self.driver = None;
394 self.future = None;
395 return true;
396 }
397
398 false
399 }
400
401 fn poll<E>(
402 &mut self,
403 id: WaiterId,
404 cx: &mut task::Context<'_>,
405 ) -> Poll<Result<S, SharedError>>
406 where
407 F: Future<Output = Result<S, E>>,
408 E: Into<BoxError>,
409 S: Clone,
410 {
411 if !self.driver.as_ref().is_some_and(|driver| driver.id == id) {
412 self.store_waker(id, cx.waker());
413 return Poll::Pending;
414 }
415
416 let future = self.future.as_mut().expect("batch future missing");
417 match future.as_mut().poll(cx) {
418 Poll::Pending => {
419 self.store_driver_waker(cx.waker());
420 Poll::Pending
421 }
422 Poll::Ready(Ok(svc)) => {
423 self.future = None;
424 Poll::Ready(Ok(svc))
425 }
426 Poll::Ready(Err(err)) => {
427 let err = box_error_into_shared(err.into());
428 self.future = None;
429 Poll::Ready(Err(err))
430 }
431 }
432 }
433
434 fn send_result(&mut self, result: Result<S, SharedError>)
435 where
436 S: Clone,
437 {
438 for waiter in std::mem::take(&mut self.waiters) {
439 let _ = waiter.tx.send(result.clone());
440 }
441 }
442
443 fn store_waker(&mut self, id: WaiterId, waker: &Waker) {
444 if let Some(waiter) = self.waiters.iter_mut().find(|waiter| waiter.id == id) {
445 if waiter
446 .waker
447 .as_ref()
448 .is_none_or(|current| !current.will_wake(waker))
449 {
450 waiter.waker = Some(waker.clone());
451 }
452 }
453 }
454
455 fn store_driver_waker(&mut self, waker: &Waker) {
456 if let Some(driver) = &mut self.driver {
457 if driver
458 .waker
459 .as_ref()
460 .is_none_or(|current| !current.will_wake(waker))
461 {
462 driver.waker = Some(waker.clone());
463 }
464 }
465 }
466
467 fn wake_driver(&mut self) {
468 if let Some(driver) = &mut self.driver {
469 if let Some(waker) = driver.waker.take() {
470 waker.wake();
471 }
472 }
473 }
474 }
475
476 #[derive(Debug)]
479 pub struct SingletonError(pub(super) SharedError);
480
481 impl SingletonError {
482 pub(super) fn new(error: BoxError) -> Self {
483 SingletonError(box_error_into_shared(error))
484 }
485 }
486
487 impl std::fmt::Display for SingletonError {
488 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
489 f.write_str("singleton connection error")
490 }
491 }
492
493 impl std::error::Error for SingletonError {
494 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
495 Some(&*self.0)
496 }
497 }
498
499 type SharedError = Arc<dyn std::error::Error + Send + Sync>;
500
501 fn box_error_into_shared(error: BoxError) -> SharedError {
502 error.into()
503 }
504}
505
506#[cfg(test)]
507mod tests {
508 use std::error::Error;
509 use std::pin::Pin;
510 use std::task::Poll;
511
512 use tower_service::Service;
513
514 use super::Singleton;
515
516 #[tokio::test]
517 async fn first_call_drives_subsequent_wait() {
518 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
519
520 let mut singleton = Singleton::new(mock_svc);
521
522 handle.allow(1);
523 std::future::poll_fn(|cx| singleton.poll_ready(cx))
524 .await
525 .unwrap();
526 let fut1 = singleton.call(());
528 let fut2 = singleton.call(());
530
531 let ((), send_response) = handle.next_request().await.unwrap();
533 send_response.send_response("svc");
534
535 fut1.await.unwrap();
537 fut2.await.unwrap();
538 }
539
540 #[tokio::test]
541 async fn made_state_returns_immediately() {
542 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
543 let mut singleton = Singleton::new(mock_svc);
544
545 handle.allow(1);
546 std::future::poll_fn(|cx| singleton.poll_ready(cx))
547 .await
548 .unwrap();
549 let fut1 = singleton.call(());
551 let ((), send_response) = handle.next_request().await.unwrap();
552 send_response.send_response("svc");
553 fut1.await.unwrap();
554
555 singleton.call(()).await.unwrap();
557 }
558
559 #[tokio::test]
560 async fn cached_service_poll_ready_error_clears_singleton() {
561 let (outer, mut outer_handle) =
563 tower_test::mock::pair::<(), tower_test::mock::Mock<(), &'static str>>();
564 let mut singleton = Singleton::new(outer);
565
566 outer_handle.allow(2);
568 std::future::poll_fn(|cx| singleton.poll_ready(cx))
569 .await
570 .unwrap();
571
572 let fut1 = singleton.call(());
574 let ((), send_inner) = outer_handle.next_request().await.unwrap();
575 let (inner, mut inner_handle) = tower_test::mock::pair::<(), &'static str>();
576 send_inner.send_response(inner);
577 let mut cached = fut1.await.unwrap();
578
579 inner_handle.allow(1);
581
582 inner_handle.send_error(std::io::Error::new(
584 std::io::ErrorKind::Other,
585 "cached poll_ready failed",
586 ));
587
588 let err = std::future::poll_fn(|cx| cached.poll_ready(cx))
590 .await
591 .err()
592 .expect("expected poll_ready error");
593 assert_eq!(err.to_string(), "cached poll_ready failed");
594
595 outer_handle.allow(1);
597 std::future::poll_fn(|cx| singleton.poll_ready(cx))
598 .await
599 .unwrap();
600 let fut2 = singleton.call(());
601 let ((), send_inner2) = outer_handle.next_request().await.unwrap();
602 let (inner2, mut inner_handle2) = tower_test::mock::pair::<(), &'static str>();
603 send_inner2.send_response(inner2);
604 let mut cached2 = fut2.await.unwrap();
605
606 inner_handle2.allow(1);
608 std::future::poll_fn(|cx| cached2.poll_ready(cx))
609 .await
610 .expect("expected poll_ready");
611 let cfut2 = cached2.call(());
612 let ((), send_cached2) = inner_handle2.next_request().await.unwrap();
613 send_cached2.send_response("svc2");
614 cfut2.await.unwrap();
615 }
616
617 #[tokio::test]
618 async fn cancel_waiter_does_not_affect_others() {
619 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
620 let mut singleton = Singleton::new(mock_svc);
621
622 std::future::poll_fn(|cx| singleton.poll_ready(cx))
623 .await
624 .unwrap();
625 let fut1 = singleton.call(());
626 let fut2 = singleton.call(());
627 drop(fut2); let ((), send_response) = handle.next_request().await.unwrap();
630 send_response.send_response("svc");
631
632 fut1.await.unwrap();
633 }
634
635 #[tokio::test]
636 async fn maker_error_is_shared_with_waiters() {
637 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
638 let mut singleton = Singleton::new(mock_svc);
639
640 std::future::poll_fn(|cx| singleton.poll_ready(cx))
641 .await
642 .unwrap();
643
644 let fut1 = singleton.call(());
645 let fut2 = singleton.call(());
646 let fut3 = singleton.call(());
647
648 let ((), send_response) = handle.next_request().await.unwrap();
649 send_response.send_error(std::io::Error::new(
650 std::io::ErrorKind::Other,
651 "maker failed",
652 ));
653
654 let err1 = fut1.await.unwrap_err();
655 let err2 = fut2.await.unwrap_err();
656 let err3 = fut3.await.unwrap_err();
657
658 let src1 = err1.source().expect("driver source");
659 let src2 = err2.source().expect("waiter source");
660 let src3 = err3.source().expect("waiter source");
661
662 assert_eq!(src1.to_string(), "maker failed");
663 assert!(std::ptr::addr_eq(src1, src2));
664 assert!(std::ptr::addr_eq(src1, src3));
665 }
666
667 #[tokio::test]
668 async fn cancel_driver_hands_off_to_waiter() {
669 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
670 let mut singleton = Singleton::new(mock_svc);
671
672 std::future::poll_fn(|cx| singleton.poll_ready(cx))
673 .await
674 .unwrap();
675 let mut fut1 = singleton.call(());
676 let fut2 = singleton.call(());
677
678 std::future::poll_fn(move |cx| {
680 let _ = Pin::new(&mut fut1).poll(cx);
681 Poll::Ready(())
682 })
683 .await;
684
685 let ((), send_response) = handle.next_request().await.unwrap();
686 send_response.send_response("svc");
687
688 fut2.await.unwrap();
689 }
690
691 #[tokio::test]
692 async fn cancel_driver_promotes_parked_waiter() {
693 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
694 let mut singleton = Singleton::new(mock_svc);
695
696 std::future::poll_fn(|cx| singleton.poll_ready(cx))
697 .await
698 .unwrap();
699 let mut fut1 = singleton.call(());
700 let fut2 = singleton.call(());
701
702 std::future::poll_fn(|cx| {
705 assert!(Pin::new(&mut fut1).poll(cx).is_pending());
706 Poll::Ready(())
707 })
708 .await;
709
710 let mut waiter = tokio_test::task::spawn(fut2);
714 assert!(waiter.poll().is_pending());
715 assert!(!waiter.is_woken());
716
717 drop(fut1);
720 assert!(waiter.is_woken());
721
722 assert!(waiter.poll().is_pending());
725
726 let ((), send_response) = handle.next_request().await.unwrap();
727 send_response.send_response("svc");
728
729 assert!(waiter.is_woken());
730 match waiter.poll() {
731 Poll::Ready(Ok(_)) => {}
732 other => panic!("expected promoted waiter to complete, got {other:?}"),
733 }
734 }
735
736 #[tokio::test]
737 async fn cancel_all_waiters_clears_singleton() {
738 let (mock_svc, _handle) = tower_test::mock::pair::<(), &'static str>();
739 let mut singleton = Singleton::new(mock_svc);
740
741 std::future::poll_fn(|cx| singleton.poll_ready(cx))
742 .await
743 .unwrap();
744 let fut1 = singleton.call(());
745 let fut2 = singleton.call(());
746
747 drop(fut1);
748 drop(fut2);
749
750 assert!(singleton.is_empty());
751 }
752
753 #[tokio::test]
754 async fn cancel_non_driver_waiter_does_not_block_others() {
755 let (mock_svc, mut handle) = tower_test::mock::pair::<(), &'static str>();
756 let mut singleton = Singleton::new(mock_svc);
757
758 std::future::poll_fn(|cx| singleton.poll_ready(cx))
759 .await
760 .unwrap();
761 let fut1 = singleton.call(());
762 let fut2 = singleton.call(());
763 let fut3 = singleton.call(());
764 drop(fut2);
765
766 let ((), send_response) = handle.next_request().await.unwrap();
767 send_response.send_response("svc");
768
769 fut1.await.unwrap();
770 fut3.await.unwrap();
771 }
772}