diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/glean/src/net | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/glean/src/net')
-rw-r--r-- | third_party/rust/glean/src/net/http_uploader.rs | 24 | ||||
-rw-r--r-- | third_party/rust/glean/src/net/mod.rs | 114 |
2 files changed, 138 insertions, 0 deletions
diff --git a/third_party/rust/glean/src/net/http_uploader.rs b/third_party/rust/glean/src/net/http_uploader.rs new file mode 100644 index 0000000000..076e005704 --- /dev/null +++ b/third_party/rust/glean/src/net/http_uploader.rs @@ -0,0 +1,24 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use crate::net::{PingUploader, UploadResult}; + +/// A simple mechanism to upload pings over HTTPS. +#[derive(Debug)] +pub struct HttpUploader; + +impl PingUploader for HttpUploader { + /// Uploads a ping to a server. + /// + /// # Arguments + /// + /// * `url` - the URL path to upload the data to. + /// * `body` - the serialized text data to send. + /// * `headers` - a vector of tuples containing the headers to send with + /// the request, i.e. (Name, Value). + fn upload(&self, url: String, _body: Vec<u8>, _headers: Vec<(String, String)>) -> UploadResult { + log::debug!("TODO bug 1675468: submitting to {:?}", url); + UploadResult::HttpStatus(200) + } +} diff --git a/third_party/rust/glean/src/net/mod.rs b/third_party/rust/glean/src/net/mod.rs new file mode 100644 index 0000000000..3ec71baf00 --- /dev/null +++ b/third_party/rust/glean/src/net/mod.rs @@ -0,0 +1,114 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +//! Handling the Glean upload logic. +//! +//! This doesn't perform the actual upload but rather handles +//! retries, upload limitations and error tracking. + +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; +use std::thread; +use std::time::Duration; + +use crate::with_glean; +use glean_core::upload::PingUploadTask; +pub use glean_core::upload::{PingRequest, UploadResult}; + +pub use http_uploader::*; + +mod http_uploader; + +/// A description of a component used to upload pings. +pub trait PingUploader: std::fmt::Debug + Send + Sync { + /// Uploads a ping to a server. + /// + /// # Arguments + /// + /// * `url` - the URL path to upload the data to. + /// * `body` - the serialized text data to send. + /// * `headers` - a vector of tuples containing the headers to send with + /// the request, i.e. (Name, Value). + fn upload(&self, url: String, body: Vec<u8>, headers: Vec<(String, String)>) -> UploadResult; +} + +/// The logic for uploading pings: this leaves the actual upload mechanism as +/// a detail of the user-provided object implementing [`PingUploader`]. +#[derive(Debug)] +pub(crate) struct UploadManager { + inner: Arc<Inner>, +} + +#[derive(Debug)] +struct Inner { + server_endpoint: String, + uploader: Box<dyn PingUploader + 'static>, + thread_running: AtomicBool, +} + +impl UploadManager { + /// Create a new instance of the upload manager. + /// + /// # Arguments + /// + /// * `server_endpoint` - the server pings are sent to. + /// * `new_uploader` - the instance of the uploader used to send pings. + pub(crate) fn new( + server_endpoint: String, + new_uploader: Box<dyn PingUploader + 'static>, + ) -> Self { + Self { + inner: Arc::new(Inner { + server_endpoint, + uploader: new_uploader, + thread_running: AtomicBool::new(false), + }), + } + } + + /// Signals Glean to upload pings at the next best opportunity. + pub(crate) fn trigger_upload(&self) { + if self.inner.thread_running.load(Ordering::SeqCst) { + log::debug!("The upload task is already running."); + return; + } + + let inner = Arc::clone(&self.inner); + + thread::Builder::new() + .name("glean.upload".into()) + .spawn(move || { + // Mark the uploader as running. + inner.thread_running.store(true, Ordering::SeqCst); + + loop { + let incoming_task = with_glean(|glean| glean.get_upload_task()); + + match incoming_task { + PingUploadTask::Upload(request) => { + let doc_id = request.document_id.clone(); + let upload_url = format!("{}{}", inner.server_endpoint, request.path); + let headers: Vec<(String, String)> = + request.headers.into_iter().collect(); + let result = inner.uploader.upload(upload_url, request.body, headers); + // Process the upload response. + with_glean(|glean| glean.process_ping_upload_response(&doc_id, result)); + } + PingUploadTask::Wait(time) => { + thread::sleep(Duration::from_millis(time)); + } + PingUploadTask::Done => { + // Nothing to do here, break out of the loop and clear the + // running flag. + inner.thread_running.store(false, Ordering::SeqCst); + return; + } + } + } + }) + .expect("Failed to spawn Glean's uploader thread"); + } +} |