2023-03-12 16:15:40 +00:00
|
|
|
use async_trait::async_trait;
|
|
|
|
use backie::{BackgroundTask, CurrentTask};
|
|
|
|
use backie::{PgTaskStore, Queue, WorkerPool};
|
2023-03-04 18:07:17 +00:00
|
|
|
use diesel_async::pg::AsyncPgConnection;
|
|
|
|
use diesel_async::pooled_connection::{bb8::Pool, AsyncDieselConnectionManager};
|
2023-03-12 16:15:40 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct MyApplicationContext {
|
|
|
|
app_name: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MyApplicationContext {
|
|
|
|
pub fn new(app_name: &str) -> Self {
|
|
|
|
Self {
|
|
|
|
app_name: app_name.to_string(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct MyTask {
|
|
|
|
pub number: u16,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MyTask {
|
|
|
|
pub fn new(number: u16) -> Self {
|
|
|
|
Self { number }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl BackgroundTask for MyTask {
|
|
|
|
const TASK_NAME: &'static str = "my_task";
|
|
|
|
type AppData = MyApplicationContext;
|
2023-03-13 16:46:59 +00:00
|
|
|
type Error = anyhow::Error;
|
2023-03-12 16:15:40 +00:00
|
|
|
|
2023-03-13 16:46:59 +00:00
|
|
|
async fn run(&self, task: CurrentTask, ctx: Self::AppData) -> Result<(), Self::Error> {
|
2023-03-12 16:15:40 +00:00
|
|
|
// let new_task = MyTask::new(self.number + 1);
|
|
|
|
// queue
|
|
|
|
// .insert_task(&new_task)
|
|
|
|
// .await
|
|
|
|
// .unwrap();
|
|
|
|
|
|
|
|
log::info!(
|
|
|
|
"[{}] Hello from {}! the current number is {}",
|
|
|
|
task.id(),
|
|
|
|
ctx.app_name,
|
|
|
|
self.number
|
|
|
|
);
|
|
|
|
tokio::time::sleep(Duration::from_secs(3)).await;
|
|
|
|
|
|
|
|
log::info!("[{}] done..", task.id());
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct MyFailingTask {
|
|
|
|
pub number: u16,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MyFailingTask {
|
|
|
|
pub fn new(number: u16) -> Self {
|
|
|
|
Self { number }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl BackgroundTask for MyFailingTask {
|
|
|
|
const TASK_NAME: &'static str = "my_failing_task";
|
|
|
|
type AppData = MyApplicationContext;
|
2023-03-13 16:46:59 +00:00
|
|
|
type Error = anyhow::Error;
|
2023-03-12 16:15:40 +00:00
|
|
|
|
2023-03-13 16:46:59 +00:00
|
|
|
async fn run(&self, task: CurrentTask, _ctx: Self::AppData) -> Result<(), Self::Error> {
|
2023-03-12 16:15:40 +00:00
|
|
|
// let new_task = MyFailingTask::new(self.number + 1);
|
|
|
|
// queue
|
|
|
|
// .insert_task(&new_task)
|
|
|
|
// .await
|
|
|
|
// .unwrap();
|
|
|
|
|
|
|
|
// task.id();
|
|
|
|
// task.keep_alive().await?;
|
|
|
|
// task.previous_error();
|
|
|
|
// task.retry_count();
|
|
|
|
|
|
|
|
log::info!("[{}] the current number is {}", task.id(), self.number);
|
|
|
|
tokio::time::sleep(Duration::from_secs(3)).await;
|
|
|
|
|
|
|
|
log::info!("[{}] done..", task.id());
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2022-07-31 13:32:37 +00:00
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
|
|
|
env_logger::init();
|
|
|
|
|
2023-03-09 15:59:45 +00:00
|
|
|
let connection_url = "postgres://postgres:password@localhost/backie";
|
2023-03-04 18:07:17 +00:00
|
|
|
|
2022-07-31 13:32:37 +00:00
|
|
|
log::info!("Starting...");
|
2022-08-27 15:58:38 +00:00
|
|
|
let max_pool_size: u32 = 3;
|
2023-03-04 18:07:17 +00:00
|
|
|
let manager = AsyncDieselConnectionManager::<AsyncPgConnection>::new(connection_url);
|
|
|
|
let pool = Pool::builder()
|
|
|
|
.max_size(max_pool_size)
|
|
|
|
.min_idle(Some(1))
|
|
|
|
.build(manager)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2023-03-09 15:59:45 +00:00
|
|
|
log::info!("Pool created ...");
|
2023-03-04 18:07:17 +00:00
|
|
|
|
2023-03-10 22:41:34 +00:00
|
|
|
let task_store = PgTaskStore::new(pool);
|
2022-07-31 13:32:37 +00:00
|
|
|
|
2023-03-09 15:59:45 +00:00
|
|
|
let (tx, mut rx) = tokio::sync::watch::channel(false);
|
2022-07-31 13:32:37 +00:00
|
|
|
|
2023-03-10 22:41:34 +00:00
|
|
|
// Some global application context I want to pass to my background tasks
|
|
|
|
let my_app_context = MyApplicationContext::new("Backie Example App");
|
2022-07-31 13:32:37 +00:00
|
|
|
|
2023-03-10 22:41:34 +00:00
|
|
|
// Register the task types I want to use and start the worker pool
|
2023-03-14 14:06:22 +00:00
|
|
|
let join_handle =
|
|
|
|
WorkerPool::new(task_store.clone(), move || my_app_context.clone())
|
2023-03-12 16:15:40 +00:00
|
|
|
.register_task_type::<MyTask>()
|
|
|
|
.register_task_type::<MyFailingTask>()
|
|
|
|
.configure_queue("default".into())
|
|
|
|
.start(async move {
|
|
|
|
let _ = rx.changed().await;
|
|
|
|
})
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-08-27 15:58:38 +00:00
|
|
|
|
2023-03-10 22:41:34 +00:00
|
|
|
log::info!("Workers started ...");
|
2022-07-31 13:32:37 +00:00
|
|
|
|
2023-03-10 22:41:34 +00:00
|
|
|
let task1 = MyTask::new(0);
|
|
|
|
let task2 = MyTask::new(20_000);
|
|
|
|
let task3 = MyFailingTask::new(50_000);
|
2022-08-04 15:22:53 +00:00
|
|
|
|
2023-03-14 14:06:22 +00:00
|
|
|
let queue = Queue::new(task_store);
|
2023-03-10 22:41:34 +00:00
|
|
|
queue.enqueue(task1).await.unwrap();
|
|
|
|
queue.enqueue(task2).await.unwrap();
|
|
|
|
queue.enqueue(task3).await.unwrap();
|
2023-03-09 15:59:45 +00:00
|
|
|
log::info!("Tasks created ...");
|
2023-03-10 22:41:34 +00:00
|
|
|
|
|
|
|
// Wait for Ctrl+C
|
|
|
|
let _ = tokio::signal::ctrl_c().await;
|
2023-03-09 15:59:45 +00:00
|
|
|
log::info!("Stopping ...");
|
|
|
|
tx.send(true).unwrap();
|
2023-03-10 22:41:34 +00:00
|
|
|
join_handle.await.unwrap();
|
|
|
|
log::info!("Workers Stopped!");
|
2022-07-31 13:32:37 +00:00
|
|
|
}
|