1use std::sync::Arc;
4use std::time::Duration;
5
6use sqlx::PgPool;
7use sqlx::postgres::PgPoolOptions;
8
9use codoseo_core::crawl::AddressPolicy;
10use codoseo_notify::{ChannelKey, GuardedHttp};
11
12use crate::auth::mailer::Mailer;
13use crate::config::{Config, Mode};
14
15#[derive(Clone)]
16pub struct AppState {
17 pub pool: PgPool,
18 pub config: Arc<Config>,
19 pub mailer: Mailer,
20 pub http: reqwest::Client,
22 pub channel_key: ChannelKey,
24 pub notify_http: GuardedHttp,
28 pub shutdown: tokio_util::sync::CancellationToken,
31 pub anon_calls: Arc<crate::agent::limiter::CallLimiter>,
33}
34
35impl AppState {
36 pub fn new(pool: PgPool, config: Config, mailer: Mailer) -> AppState {
37 let policy = match config.mode {
38 Mode::Cloud => AddressPolicy::Public,
39 Mode::SelfHost => AddressPolicy::AllowPrivate,
40 };
41 AppState {
42 pool,
43 channel_key: ChannelKey::derive(&config.secret_key),
44 notify_http: GuardedHttp::new(policy).expect("http client builds"),
45 config: Arc::new(config),
46 mailer,
47 shutdown: tokio_util::sync::CancellationToken::new(),
48 anon_calls: Arc::new(crate::agent::limiter::CallLimiter::for_anon_tools()),
49 http: reqwest::Client::builder()
50 .timeout(Duration::from_secs(10))
51 .user_agent(concat!("CodoSEO/", env!("CARGO_PKG_VERSION")))
52 .build()
53 .expect("http client builds"),
54 }
55 }
56}
57
58pub fn lazy_pool(database_url: &str) -> Result<PgPool, sqlx::Error> {
61 PgPoolOptions::new()
62 .max_connections(5)
63 .acquire_timeout(Duration::from_secs(3))
64 .connect_lazy(database_url)
65}