1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45use fuchsia_sync::Mutex;
6use futures::channel::mpsc;
7use log::{info, warn};
8use std::sync::atomic::{AtomicBool, Ordering};
9use std::sync::Arc;
1011/// Capacity of "first come, first serve" slots available to clients of
12/// the mpsc::Sender<TelemetryEvent>.
13pub const TELEMETRY_EVENT_BUFFER_SIZE: usize = 100;
1415#[derive(Clone, Debug)]
16pub struct TelemetrySender {
17 sender: Arc<Mutex<mpsc::Sender<crate::TelemetryEvent>>>,
18 sender_is_blocked: Arc<AtomicBool>,
19}
2021impl TelemetrySender {
22pub fn new(sender: mpsc::Sender<crate::TelemetryEvent>) -> Self {
23Self {
24 sender: Arc::new(Mutex::new(sender)),
25 sender_is_blocked: Arc::new(AtomicBool::new(false)),
26 }
27 }
2829// Send telemetry event. Log an error if it fails
30pub fn send(&self, event: crate::TelemetryEvent) {
31match self.sender.lock().try_send(event) {
32Ok(_) => {
33// If sender has been blocked before, set bool to false and log message
34if self
35.sender_is_blocked
36 .compare_exchange(true, false, Ordering::SeqCst, Ordering::SeqCst)
37 .is_ok()
38 {
39info!("TelemetrySender recovered and resumed sending");
40 }
41 }
42Err(_) => {
43// If sender has not been blocked before, set bool to true and log error message
44if self
45.sender_is_blocked
46 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
47 .is_ok()
48 {
49warn!("TelemetrySender dropped a msg: either buffer is full or no receiver is waiting");
50 }
51 }
52 }
53 }
54}