e40c667
use std::sync::Arc;
use ::bootstrap::AppState;
/// Everything a request handler needs, built once at startup.
///
/// The actix worker closure only clones this value; no pool, client or
/// service handle is created per worker thread.
#[derive(Clone)]
pub struct Deps {
pub state: AppState,
pub accounts: auth::Accounts,
pub access: space::Access,
pub notifications: push::notify::Notifications,
pub auth: auth::AuthService,
pub chat: chat::services::service::ChatService,
pub issues: issues::services::service::IssueService,
pub space: space::services::service::SpaceService,
pub user: user::services::service::UserService,
pub git: git::service::GitService,
pub pulls: pulls::services::service::PullService,
pub internal_service_key: String,
}
impl Deps {
pub fn new(state: AppState, sessions: auth::session::RedisStore) -> Self {
let accounts =
auth::Accounts::new(state.database.connection().clone(), state.cache.clone());
let access = space::Access::new(state.database.connection().clone(), state.cache.clone());
let notifications =
push::notify::Notifications::new(state.database.clone(), state.redis.clone());
let auth = auth::AuthService::new(
accounts.clone(),
auth::services::AuthSettings::from_config(&state.config),
state.mail.clone(),
sessions,
);
let issue_audience = issues::services::audience::Audience::new(
accounts.clone(),
notifications.clone(),
state.mail.clone(),
i18n::config_fallback(state.config.email.default_locale()),
);
let issues = issues::services::service::IssueService::new(
state.database.clone(),
state.storage.clone(),
issue_audience,
issues::services::service::IssueSettings::from_config(&state.config),
issues::services::admission::Admission::new(
access.clone(),
state.redis.clone(),
state.config.quota.clone(),
),
);
let space = space::services::service::SpaceService::new(
access.clone(),
space::services::images::SpaceImages::new(
access.clone(),
state.storage.clone(),
state.redis.clone(),
),
space::services::policy::SpacePolicy::new(
space::services::service::SpaceSettings::from_config(&state.config),
accounts.clone(),
state.redis.clone(),
),
notifications.clone(),
);
let chat = build_chat_service(&state, &accounts, ¬ifications, &access, &space);
let user = user::services::service::UserService::new(
state.database.clone(),
accounts.clone(),
access.clone(),
user::services::avatar::AvatarService::new(
state.database.clone(),
state.storage.clone(),
state.redis.clone(),
),
);
let git_config = state.config.git.clone();
let kenshell = proto::KenShellClient::connect_with_key(
&git_config.kenshell_endpoint,
&git_config.kenshell_rpc_key,
std::time::Duration::from_secs(git_config.kenshell_timeout_secs.max(1)),
)
.unwrap_or_else(|error| {
panic!(
"invalid git.kenshell_endpoint `{}`: {error}",
git_config.kenshell_endpoint
)
})
.with_request_id(api::middleware::request_id);
let git = git::service::GitService::new(
state.database.clone(),
accounts.clone(),
access.clone(),
git::service::GitBackend::new(state.cache.clone(), git_config, Arc::new(kenshell)),
);
let pulls = pulls::services::service::PullService::new(
state.database.clone(),
git.clone(),
issues.clone(),
pulls::services::actors::Actors::new(
accounts.clone(),
state.redis.clone(),
state.config.quota.clone(),
),
);
let internal_service_key = state.config.internal.service_key.clone();
Self {
state,
accounts,
access,
notifications,
auth,
chat,
issues,
space,
user,
git,
pulls,
internal_service_key,
}
}
}
fn build_chat_service(
state: &AppState,
accounts: &auth::Accounts,
notifications: &push::notify::Notifications,
access: &space::Access,
space: &space::services::service::SpaceService,
) -> chat::services::service::ChatService {
let audience = chat::services::audience::Audience::new(
accounts.clone(),
notifications.clone(),
state.mail.clone(),
chat::share::realtime::Realtime::new(state.database.clone()),
i18n::config_fallback(state.config.email.default_locale()),
);
let participants = chat::services::presence::Participants::new(
state.database.clone(),
state.redis.clone(),
access.clone(),
audience.clone(),
chat::services::presence::ParticipantSettings::from_config(&state.config),
);
chat::services::service::ChatService::new(
state.database.clone(),
chat::services::media::Media::new(
state.storage.clone(),
state.redis.clone(),
state.database.clone(),
),
audience,
chat::services::service::ChatSettings::from_config(&state.config),
participants,
space.clone(),
)
}