Client side atproto account migrator in your web browser, along with services for backups and adversarial migrations.
pdsmoover.com
pds
atproto
migrations
moo
cow
1use apalis::prelude::*;
2use apalis_cron::{CronStream, Schedule};
3use apalis_sql::postgres::PgPool;
4use apalis_sql::sqlx::types::chrono::Utc;
5use dotenvy::dotenv;
6use log::{debug, info};
7use shared::jobs::start_all_backup::start_all_backup;
8use std::env;
9use std::str::FromStr;
10use std::time::Duration;
11use tower::load_shed::LoadShedLayer;
12use tracing_subscriber::prelude::*;
13
14#[tokio::main]
15async fn main() -> Result<(), Box<dyn std::error::Error>> {
16 use tracing_subscriber::EnvFilter;
17 let _ = dotenv();
18 let fmt_layer = tracing_subscriber::fmt::layer().with_target(false);
19 let filter_layer =
20 EnvFilter::try_from_default_env().or_else(|_| EnvFilter::try_new("debug"))?;
21 tracing_subscriber::registry()
22 .with(filter_layer)
23 .with(fmt_layer)
24 .init();
25
26 // Job backend setup (DB only needed to record/run backups in start_all_backup)
27 let database_url = std::env::var("DATABASE_URL").expect("Must specify path to db");
28 let pool = PgPool::connect(&database_url).await?;
29
30 // Default to run at the 0th second and minute of every hour, i.e. every hour
31 // Job is currently set to only do backups within a 24 hour period
32 // 6-field cron: second minute hour day month weekday
33 let backup_schedule = env::var("BACKUP_SCHEDULE").unwrap_or("0 0 */1 * * *".to_string());
34 let schedule = Schedule::from_str(backup_schedule.as_str()).unwrap();
35 log::info!("Using BACKUP_SCHEDULE: {}", backup_schedule);
36
37 Monitor::new()
38 .register({
39 WorkerBuilder::new("cron-start")
40 .data(pool.clone())
41 .enable_tracing()
42 .layer(LoadShedLayer::new())
43 //Can be removed just a small safe guard if something goes wrong to help catch overloading the job runner
44 .rate_limit(1, Duration::from_secs(60 * 5))
45 .backend(CronStream::new_with_timezone(schedule, Utc))
46 .build_fn(start_all_backup)
47 })
48 .on_event(|e| debug!("{e}"))
49 .run_with_signal(async {
50 tokio::signal::ctrl_c().await?;
51 info!("Shutting down the cron worker");
52 Ok(())
53 })
54 .await?;
55
56 Ok(())
57}