use restate_sdk::prelude::*;
use std::time::Duration;
#[restate_sdk::object]
trait PeriodicTask {
async fn start() -> Result<(), TerminalError>;
async fn stop() -> Result<(), TerminalError>;
async fn run() -> Result<(), TerminalError>;
}
struct PeriodicTaskImpl;
const ACTIVE: &str = "active";
impl PeriodicTask for PeriodicTaskImpl {
async fn start(&self, context: ObjectContext<'_>) -> Result<(), TerminalError> {
if context
.get::<bool>(ACTIVE)
.await?
.is_some_and(|enabled| enabled)
{
return Ok(());
}
PeriodicTaskImpl::schedule_next(&context);
context.set(ACTIVE, true);
Ok(())
}
async fn stop(&self, context: ObjectContext<'_>) -> Result<(), TerminalError> {
context.clear(ACTIVE);
Ok(())
}
async fn run(&self, context: ObjectContext<'_>) -> Result<(), TerminalError> {
if context.get::<bool>(ACTIVE).await?.is_none() {
return Ok(());
}
println!("Triggered the periodic task!");
PeriodicTaskImpl::schedule_next(&context);
Ok(())
}
}
impl PeriodicTaskImpl {
fn schedule_next(context: &ObjectContext<'_>) {
context
.object_client::<PeriodicTaskClient>(context.key())
.run()
.send_after(Duration::from_secs(10));
}
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
HttpServer::new(Endpoint::builder().bind(PeriodicTaskImpl.serve()).build())
.listen_and_serve("0.0.0.0:9080".parse().unwrap())
.await;
}