#[cfg(feature = "batch")]
use arrrg::CommandLine;
#[cfg(feature = "batch")]
use arrrg_derive::CommandLine;
#[cfg(feature = "batch")]
use langcontinuation::batch::visualizer::{
HtmlOptions, VisualizationOptions, build_root_workflow_visualization, render_visualization_html,
};
#[cfg(feature = "batch")]
const USAGE: &str = "\
Usage: batch_visualizer [OPTIONS]
Generate a self-contained HTML artifact for one batch root workflow.
";
#[cfg(feature = "batch")]
#[derive(Clone, Debug, Default, Eq, PartialEq, CommandLine)]
struct Options {
#[arrrg(required, "Root workflow run id to visualize.", "RUN")]
root_run_id: String,
#[arrrg(required, "Path to write the generated HTML artifact.", "PATH")]
output: String,
#[arrrg(optional, "Postgres database URL. Defaults to DATABASE_URL.", "URL")]
database_url: Option<String>,
#[arrrg(optional, "Maximum events to embed before failing.", "N")]
max_events: Option<usize>,
#[arrrg(flag, "Include full workflow/continuation/provider error strings.")]
include_errors: bool,
#[arrrg(
flag,
"Include workflow snapshots and continuation/provider request and response bodies."
)]
break_glass: bool,
}
#[cfg(feature = "batch")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = std::env::args().skip(1).collect::<Vec<_>>();
let arg_refs = args.iter().map(String::as_str).collect::<Vec<_>>();
let (options, free) = Options::from_arguments_relaxed(USAGE, &arg_refs);
if !free.is_empty() {
eprintln!(
"unexpected positional arguments: {}\n\n{USAGE}",
free.join(" ")
);
std::process::exit(64);
}
let database_url = match options
.database_url
.or_else(|| std::env::var("DATABASE_URL").ok())
{
Some(database_url) => database_url,
None => {
eprintln!("--database-url or DATABASE_URL is required\n\n{USAGE}");
std::process::exit(64);
}
};
let pool = sqlx::PgPool::connect(&database_url).await?;
let document = build_root_workflow_visualization(
&pool,
&options.root_run_id,
VisualizationOptions {
include_errors: options.include_errors,
break_glass: options.break_glass,
max_events: options
.max_events
.unwrap_or_else(|| VisualizationOptions::default().max_events),
},
)
.await?;
let html = render_visualization_html(
&document,
HtmlOptions {
title: Some(format!("Batch workflow {}", options.root_run_id)),
},
)?;
std::fs::write(&options.output, html)?;
println!(
"wrote {} events for root {} to {}",
document.overview.total_events, document.root_run_id, options.output
);
Ok(())
}
#[cfg(not(feature = "batch"))]
fn main() {
eprintln!("rebuild with `--features batch` to use the batch visualizer example");
std::process::exit(64);
}