I try to build a REST with Rocket, that allows the caller to configure times at which he will be unavailable. Therefore it can either happen, that the unavailability has to be started immediately or I have to store it in a database for later execution.
I can implement all this with a normal set up of Rocket, rocket_sync_db_pools and Diesel:
#[database("postgres_diesel")]
pub struct DbConn(diesel::PgConnection);
#[rocket::main]
async fn main() {
rocket::build()
.attach(DbConn::fairing())
.mount(
"/v1",
routes![ post_block ],
)
.launch()
.await
.expect("could not launch rocket");
}
Within the handler function for the incoming requests I can get the database connection:
#[post("/block", data = "<new_block>")]
pub async fn post_block(
new_block: Json<NewBlock>,
conn: DbConn,
) -> Result<Json<Block>, BadRequest<&'static str>> {
Ok(Json(conn.run(move |c| configure_block(new_block.0, c)).await))
}
Within the implementation of configure_block()
I either execute the configuration immediately or write it as a job to the database.
But how can I execute the configuration changes written to the database at a later moment? I need something like a cronjob within Rocket within that I can check the database, if there are pending jobs.
I tried to do it using tokio::time::interval
which will run my task repeatedly. But I cannot get access to by DbPool
within this tokio timer. I cannot use DbPool::get_one(&Rocket)
as I don't have access to my rocket instance.
So I wonder: how can I run a repeated task within rocket?