Skip to content
This repository was archived by the owner on Apr 4, 2026. It is now read-only.

Commit 1e5c774

Browse files
feat(cli): wire up root_parent backfill command
Add CLI interface for the root_parent backfill module that was added in v2026.1.2 but not exposed via the command line. New command: waypoint backfill root-parent --url-parents: Backfill casts with URL parents (simple SQL update) --hash-parents: Backfill casts with hash-based parents (Hub traversal) --all: Run both operations --batch-size, --max-depth, --batch-delay: Tuning options
1 parent d6a58a6 commit 1e5c774

2 files changed

Lines changed: 149 additions & 0 deletions

File tree

src/commands/backfill/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod bench;
22
pub mod fid;
33
pub mod onchain_events;
4+
pub mod root_parent;
45

56
use clap::{ArgMatches, Command};
67
use color_eyre::eyre::Result;
@@ -27,6 +28,9 @@ pub fn register_commands(app: Command) -> Command {
2728
.value_name("COUNT")
2829
.help("Number of messages to generate for the benchmark")
2930
.default_value("10000")))
31+
// Root parent backfill commands
32+
.subcommand(root_parent::register_commands(Command::new("root-parent")
33+
.about("Backfill root_parent columns for existing casts")))
3034
}
3135

3236
/// Handle backfill commands based on matches
@@ -36,6 +40,7 @@ pub async fn handle_command(matches: &ArgMatches, config: &Config) -> Result<()>
3640
Some(("onchain-events", submatches)) => {
3741
onchain_events::handle_command(submatches, config).await
3842
},
43+
Some(("root-parent", submatches)) => root_parent::handle_command(submatches, config).await,
3944
Some(("bench", submatches)) => {
4045
// Get the message count parameter
4146
let messages = submatches
@@ -71,13 +76,15 @@ pub async fn handle_command(matches: &ArgMatches, config: &Config) -> Result<()>
7176
println!("Please specify a backfill subcommand. Available command groups:");
7277
println!(" fid - FID-based backfill operations");
7378
println!(" onchain-events - Backfill onchain events for Farcaster FIDs");
79+
println!(" root-parent - Backfill root_parent columns for casts");
7480
println!(" bench - Database benchmark operations");
7581
Ok(())
7682
},
7783
Some((cmd, _)) => {
7884
println!("Unknown command group: {}. Available command groups:", cmd);
7985
println!(" fid - FID-based backfill operations");
8086
println!(" onchain-events - Backfill onchain events for Farcaster FIDs");
87+
println!(" root-parent - Backfill root_parent columns for casts");
8188
println!(" bench - Database benchmark operations");
8289
Ok(())
8390
},
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
use clap::{Arg, ArgMatches, Command};
2+
use color_eyre::eyre::Result;
3+
use std::sync::Arc;
4+
use tokio::sync::Mutex;
5+
use tracing::{error, info};
6+
use waypoint::{
7+
backfill::root_parent::{RootParentBackfill, RootParentBackfillConfig, backfill_url_parents},
8+
config::Config,
9+
hub::client::Hub,
10+
};
11+
12+
/// Register root_parent backfill commands
13+
pub fn register_commands(app: Command) -> Command {
14+
app.about("Backfill root_parent columns for existing casts")
15+
.arg_required_else_help(true)
16+
.arg(
17+
Arg::new("hash-parents")
18+
.long("hash-parents")
19+
.help("Backfill casts with hash-based parents (requires Hub traversal)")
20+
.action(clap::ArgAction::SetTrue),
21+
)
22+
.arg(
23+
Arg::new("url-parents")
24+
.long("url-parents")
25+
.help("Backfill casts with URL parents (simple SQL update)")
26+
.action(clap::ArgAction::SetTrue),
27+
)
28+
.arg(
29+
Arg::new("all")
30+
.long("all")
31+
.help("Backfill both hash-based and URL parents")
32+
.action(clap::ArgAction::SetTrue),
33+
)
34+
.arg(
35+
Arg::new("batch-size")
36+
.long("batch-size")
37+
.value_name("SIZE")
38+
.help("Number of casts to process per batch (hash-parents only)")
39+
.default_value("100")
40+
.value_parser(clap::value_parser!(usize)),
41+
)
42+
.arg(
43+
Arg::new("max-depth")
44+
.long("max-depth")
45+
.value_name("DEPTH")
46+
.help("Maximum parent chain depth to traverse (hash-parents only)")
47+
.default_value("100")
48+
.value_parser(clap::value_parser!(usize)),
49+
)
50+
.arg(
51+
Arg::new("batch-delay")
52+
.long("batch-delay")
53+
.value_name("MS")
54+
.help("Delay between batches in milliseconds (hash-parents only)")
55+
.default_value("100")
56+
.value_parser(clap::value_parser!(u64)),
57+
)
58+
}
59+
60+
/// Handle root_parent backfill command
61+
pub async fn handle_command(matches: &ArgMatches, config: &Config) -> Result<()> {
62+
let hash_parents = matches.get_flag("hash-parents");
63+
let url_parents = matches.get_flag("url-parents");
64+
let all = matches.get_flag("all");
65+
66+
let batch_size = *matches.get_one::<usize>("batch-size").unwrap();
67+
let max_depth = *matches.get_one::<usize>("max-depth").unwrap();
68+
let batch_delay = *matches.get_one::<u64>("batch-delay").unwrap();
69+
70+
if !hash_parents && !url_parents && !all {
71+
println!("Please specify one of: --all, --hash-parents, or --url-parents");
72+
return Ok(());
73+
}
74+
75+
let do_hash = hash_parents || all;
76+
let do_url = url_parents || all;
77+
78+
info!("Initializing resources for root_parent backfill...");
79+
80+
// Initialize database
81+
let database = waypoint::database::client::Database::new(&config.database).await?;
82+
let pool = &database.pool;
83+
84+
// Run URL parents backfill (simple SQL, no Hub needed)
85+
if do_url {
86+
info!("Backfilling URL parents...");
87+
match backfill_url_parents(pool).await {
88+
Ok(count) => {
89+
info!("URL parents backfill complete: {} casts updated", count);
90+
},
91+
Err(e) => {
92+
error!("URL parents backfill failed: {}", e);
93+
if !do_hash {
94+
std::process::exit(1);
95+
}
96+
},
97+
}
98+
}
99+
100+
// Run hash parents backfill (requires Hub traversal)
101+
if do_hash {
102+
info!("Backfilling hash-based parents (this may take a while)...");
103+
104+
// Initialize Hub client
105+
let hub = Arc::new(Mutex::new(Hub::new(config.hub.clone())?));
106+
107+
// Connect to Hub
108+
{
109+
let mut hub_guard = hub.lock().await;
110+
if !hub_guard.check_connection().await.unwrap_or(false) {
111+
error!("Failed to connect to Hub - required for hash-based backfill");
112+
std::process::exit(1);
113+
}
114+
}
115+
116+
let backfill_config =
117+
RootParentBackfillConfig { batch_size, max_depth, batch_delay_ms: batch_delay };
118+
119+
let backfiller = RootParentBackfill::new(pool.clone(), hub, backfill_config);
120+
121+
match backfiller.run().await {
122+
Ok(stats) => {
123+
info!("Hash parents backfill complete:");
124+
info!(" Casts processed: {}", stats.casts_processed);
125+
info!(" Roots found: {}", stats.roots_found);
126+
info!(" Broken chains: {}", stats.chains_broken);
127+
info!(" Errors: {}", stats.errors);
128+
129+
if stats.errors > 0 {
130+
std::process::exit(1);
131+
}
132+
},
133+
Err(e) => {
134+
error!("Hash parents backfill failed: {}", e);
135+
std::process::exit(1);
136+
},
137+
}
138+
}
139+
140+
info!("Root parent backfill completed successfully!");
141+
Ok(())
142+
}

0 commit comments

Comments
 (0)