viaduct/
backend.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use crate::{info, settings::validate_request, trace};
6use ffi::FfiBackend;
7use once_cell::sync::OnceCell;
8mod ffi;
9
10pub fn note_backend(which: &str) {
11    // If trace logs are enabled: log on every request. Otherwise, just log on
12    // the first request at `info` level. We remember if the Once was triggered
13    // to avoid logging twice in the first case.
14    static NOTE_BACKEND_ONCE: std::sync::Once = std::sync::Once::new();
15    let mut called = false;
16    NOTE_BACKEND_ONCE.call_once(|| {
17        info!("Using HTTP backend {}", which);
18        called = true;
19    });
20    if !called {
21        trace!("Using HTTP backend {}", which);
22    }
23}
24
25pub trait Backend: Send + Sync + 'static {
26    fn send(&self, request: crate::Request) -> Result<crate::Response, crate::ViaductError>;
27}
28
29static BACKEND: OnceCell<&'static dyn Backend> = OnceCell::new();
30
31pub fn set_backend(b: &'static dyn Backend) -> Result<(), crate::ViaductError> {
32    BACKEND
33        .set(b)
34        .map_err(|_| crate::error::ViaductError::SetBackendError)
35}
36
37pub(crate) fn get_backend() -> &'static dyn Backend {
38    *BACKEND.get_or_init(|| Box::leak(Box::new(FfiBackend)))
39}
40
41pub fn send(request: crate::Request) -> Result<crate::Response, crate::ViaductError> {
42    validate_request(&request)?;
43    get_backend().send(request)
44}