Skip to main content

lfsx_server/
state.rs

1use std::sync::Arc;
2
3use tokio::sync::Semaphore;
4
5use crate::auth::Authorizer;
6use crate::config::Config;
7use crate::locks::LockStore;
8use crate::metrics::Metrics;
9use crate::storage::Store;
10
11pub struct AppState {
12    pub store: Store,
13    pub locks: LockStore,
14    pub config: Config,
15    pub authorizer: Authorizer,
16    pub metrics: Metrics,
17    // None when the cap is configured off. A permit is held for as long as a
18    // transfer keeps bytes moving, which for a download means as long as the
19    // client keeps reading the body, so the permit travels with the stream.
20    pub transfers: Option<Arc<Semaphore>>,
21}
22
23impl AppState {
24    // A permit, or the refusal that tells the client when to come back. Taken
25    // without waiting: a saturated server queueing acceptances would hold the
26    // connection open for the privilege of being slow later, and an immediate
27    // answer with Retry-After lets the client spend the wait on its side.
28    pub fn transfer_permit(
29        &self,
30    ) -> Result<Option<tokio::sync::OwnedSemaphorePermit>, crate::error::Error> {
31        match &self.transfers {
32            None => Ok(None),
33            Some(transfers) => match transfers.clone().try_acquire_owned() {
34                Ok(permit) => Ok(Some(permit)),
35                Err(_) => Err(crate::error::Error::TransfersSaturated { retry_after: 5 }),
36            },
37        }
38    }
39}
40
41pub type Shared = Arc<AppState>;