mod common;
use std::time::Duration;
use common::RunningWorker;
use serde::{Deserialize, Serialize};
use steda::{Error, Result, RetryStrategy, Task, TaskContext};
#[derive(Debug, Deserialize, Serialize)]
struct MetricProbeInput {
label: String,
should_fail: bool,
}
#[derive(Debug, Deserialize, Serialize)]
struct MetricProbeOutput {
label: String,
}
const METRIC_PROBE: Task<MetricProbeInput, MetricProbeOutput> = Task::new("metric-probe");
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
let steda = common::connect().await?;
let queue = steda.queue("example-metrics")?;
queue.create().await?;
let metrics = queue.metrics();
let worker = queue
.worker()
.task(METRIC_PROBE, async |input: MetricProbeInput, _ctx: TaskContext| {
if input.should_fail {
return Err(Error::Other("simulated application failure".to_owned()));
}
Ok(MetricProbeOutput { label: input.label })
})
.build()?;
let worker_metrics = worker.metrics();
let worker = RunningWorker::start(worker);
let successful = queue
.spawn(METRIC_PROBE, MetricProbeInput { label: "completed".to_owned(), should_fail: false })
.await?;
let failing = queue
.spawn(
METRIC_PROBE,
MetricProbeInput { label: "failed attempt".to_owned(), should_fail: true },
)
.max_attempts(1)
.retry_strategy(RetryStrategy::none())
.await?;
let output = successful.result_with_timeout(Duration::from_secs(10)).await?;
println!("successful task: {}", output.label);
match failing.result_with_timeout(Duration::from_secs(10)).await {
Err(Error::TaskFailed { .. }) => println!("failing task: failed as expected"),
Err(error) => return Err(error),
Ok(output) => {
return Err(Error::Other(format!("expected failure, got success: {}", output.label)));
}
}
worker.stop().await?;
assert_eq!(worker_metrics.executions(), metrics.executions());
println!("queue metrics:");
println!(" claimed runs: {}", metrics.claimed_runs());
println!(" claim errors: {}", metrics.claim_errors());
println!(" executions: {}", metrics.executions());
println!(" completed: {}", metrics.completed_executions());
println!(" failed: {}", metrics.failed_executions());
println!(" lease lost: {}", metrics.lease_lost_executions());
println!(" cancelled: {}", metrics.cancelled_executions());
println!(" suspended: {}", metrics.suspended_executions());
println!(" unhandled: {}", metrics.unhandled_executions());
let execution_duration = Duration::from_nanos(metrics.execution_duration_nanoseconds());
println!(" cumulative execution time: {} µs", execution_duration.as_micros());
Ok(())
}