Skip to main content

max / makenotwork

Perf: batch bundle lookup; stop gating git info/refs on the clone budget - item page: replace the per-id get_item_by_id loop over an unlisted item's containing bundles with a single get_public_items_by_ids (ANY($1)) query. - git: don't acquire git_smart_http_semaphore for info/refs. The ref advertisement is a short bounded child (KB-sized, exits immediately) and is GovernorLayer-rate-limited; sharing the upload-pack budget let a burst of slow clones stall every new clone at the handshake. The cap now covers the expensive streaming upload-pack only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-06-15 23:36 UTC
Commit: 4e3b79998b1dd754c8dd50fe868a096fbbb81298
Parent: f0f01c9
3 files changed, +28 insertions, -19 deletions
@@ -115,6 +115,24 @@ pub async fn get_item_by_id(pool: &PgPool, id: ItemId) -> Result<Option<DbItem>>
115 115 Ok(item)
116 116 }
117 117
118 + /// Fetch multiple public items by id in one query. Replaces a per-id
119 + /// `get_item_by_id` loop (N+1) where the caller only wants the public rows.
120 + /// Order is not guaranteed.
121 + #[tracing::instrument(skip_all)]
122 + pub async fn get_public_items_by_ids(pool: &PgPool, ids: &[ItemId]) -> Result<Vec<DbItem>> {
123 + if ids.is_empty() {
124 + return Ok(Vec::new());
125 + }
126 + let items = sqlx::query_as::<_, DbItem>(
127 + "SELECT * FROM items WHERE id = ANY($1) AND is_public = true",
128 + )
129 + .bind(ids)
130 + .fetch_all(pool)
131 + .await?;
132 +
133 + Ok(items)
134 + }
135 +
118 136 /// Fetch titles for a batch of item IDs. Returns (item_id, title) pairs.
119 137 #[tracing::instrument(skip_all)]
120 138 pub async fn get_item_titles_batch(pool: &PgPool, ids: &[ItemId]) -> Result<Vec<(ItemId, String)>> {
@@ -110,14 +110,13 @@ pub(super) async fn smart_http_info_refs(
110 110 let root = repos_root(&state)?;
111 111 let repo_path = git::repo_disk_path(&root, &owner, repo_name)?;
112 112
113 - // Same per-clone permit as upload-pack; the ref advertisement is a `git`
114 - // child too, so it shares the fan-out budget.
115 - let _permit = state
116 - .git_smart_http_semaphore
117 - .acquire()
118 - .await
119 - .context("acquire git smart-http permit")?;
120 -
113 + // The ref advertisement is NOT gated by `git_smart_http_semaphore`: it's a
114 + // short, bounded `git upload-pack --advertise-refs` that buffers only the
115 + // (KB-sized) ref list and exits immediately, and the route is already
116 + // rate-limited by the GovernorLayer. Sharing the upload-pack budget made a
117 + // burst of slow clones (holding their permits during the pack transfer)
118 + // stall every *new* clone at the handshake — the budget is for the
119 + // expensive streaming half only (Run #21 Performance).
121 120 let output = tokio::process::Command::new("git")
122 121 .arg("upload-pack")
123 122 .arg("--stateless-rpc")
@@ -113,17 +113,9 @@ pub(crate) async fn render_item_page(
113 113 } else {
114 114 vec![]
115 115 };
116 - let containing_bundles: Vec<db::DbItem> = {
117 - let mut bundles = Vec::new();
118 - for bid in &containing_bundle_ids {
119 - if let Some(b) = db::items::get_item_by_id(&state.db, *bid).await?
120 - && b.is_public
121 - {
122 - bundles.push(b);
123 - }
124 - }
125 - bundles
126 - };
116 + // Single batched query instead of one get_item_by_id per bundle id (N+1).
117 + let containing_bundles: Vec<db::DbItem> =
118 + db::items::get_public_items_by_ids(&state.db, &containing_bundle_ids).await?;
127 119
128 120 // For bundle-type items, load the child items
129 121 let bundle_child_items = if db_item.item_type == ItemType::Bundle {