diff --git a/src/api/router/snapshot_descriptor_upgrade_tests.rs b/src/api/router/snapshot_descriptor_upgrade_tests.rs index 9cb37b3b..c57bc57b 100644 --- a/src/api/router/snapshot_descriptor_upgrade_tests.rs +++ b/src/api/router/snapshot_descriptor_upgrade_tests.rs @@ -85,7 +85,20 @@ async fn captured_87b_descriptor_upgrade_preserves_owners_oids_and_replays_missi ) .await .unwrap(); + let reader = core.begin().await.unwrap(); + let registrations = reader + .query_one_raw(Statement::from_string( + DbBackend::Postgres, + "SELECT (SELECT count(*) FROM mst2_metadata_namespace) AS namespaces, + (SELECT count(*) FROM mst2_qualified_family_policy) AS policies", + )) + .await + .unwrap() + .unwrap(); + assert_eq!(registrations.try_get::("", "namespaces").unwrap(), 2); + assert_eq!(registrations.try_get::("", "policies").unwrap(), 1); apply_migrations(core, false).await.unwrap(); + reader.rollback().await.unwrap(); assert_upgrade_ledgers(core).await; assert_eq!(descriptor_matches_stored(&fixture).await, 1); assert_eq!(policy(core).await, stamp); diff --git a/src/api/router/snapshot_reader_retention_tests.rs b/src/api/router/snapshot_reader_retention_tests.rs index 52890bd7..3feadd29 100644 --- a/src/api/router/snapshot_reader_retention_tests.rs +++ b/src/api/router/snapshot_reader_retention_tests.rs @@ -266,14 +266,32 @@ async fn stale_actual_reader_cannot_read_or_finish_a_reissued_uuid() { ), ); let app = fixture.app.clone(); - let pending = tokio::spawn(with_rooted_reader_barriers( + let mut pending = tokio::spawn(with_rooted_reader_barriers( admitted.clone(), resume.clone(), async move { app.oneshot(request).await.unwrap() }, )); - tokio::time::timeout(Duration::from_secs(4), admitted.wait()) - .await - .unwrap(); + // Admission includes a database lock wait of up to five seconds and a + // committed owner. Observe an early HTTP failure as well as the barrier. + let admission = tokio::time::timeout(Duration::from_secs(30), async { + tokio::select! { + _ = admitted.wait() => {} + response = &mut pending => { + let response = response.unwrap(); + let status = response.status(); + let body = to_bytes(response.into_body(), 16 * 1024).await.unwrap(); + panic!( + "reader request ended before its admission barrier: {status}: {}", + String::from_utf8_lossy(&body) + ); + } + } + }) + .await; + if let Err(error) = admission { + pending.abort(); + panic!("reader admission barrier timed out: {error}"); + } let txn = transaction(&fixture).await; let owner=txn.query_one_raw(Statement::from_string(DbBackend::Postgres, "SELECT operation_id::text,reader_issuance,to_jsonb(r) AS owner FROM mst2_metadata_reader_operation r WHERE state='ACTIVE'")) @@ -333,7 +351,7 @@ async fn stale_actual_reader_cannot_read_or_finish_a_reissued_uuid() { [old.0.clone().into(),next.into(),source_id.into(),source_root.into(),source_generation.into(),source_certificate.into()])).await.unwrap().is_empty()); txn.commit().await.unwrap(); resume.wait().await; - let response = tokio::time::timeout(Duration::from_secs(4), pending) + let response = tokio::time::timeout(Duration::from_secs(30), pending) .await .unwrap() .unwrap(); diff --git a/src/jupiter/migration/qualified_native_runtime_upgrade.rs b/src/jupiter/migration/qualified_native_runtime_upgrade.rs index 85cd256b..0aeaba5f 100644 --- a/src/jupiter/migration/qualified_native_runtime_upgrade.rs +++ b/src/jupiter/migration/qualified_native_runtime_upgrade.rs @@ -391,8 +391,11 @@ async fn upgrade_to( )) .await?; } + // Route admission reads these immutable registrations before waiting for + // mono. Exclude concurrent writers and DDL while allowing those reads to + // complete without a relation-lock/mono-lock cycle. connection.execute_unprepared(&format!( - "LOCK TABLE {c}.mst2_metadata_namespace,{c}.mst2_qualified_family_policy IN ACCESS EXCLUSIVE MODE" + "LOCK TABLE {c}.mst2_metadata_namespace,{c}.mst2_qualified_family_policy IN SHARE ROW EXCLUSIVE MODE" )).await?; let policy=connection.query_one_raw(Statement::from_string(DbBackend::Postgres, format!("SELECT implementation_fingerprint,expected_shape,authority_catalog FROM {c}.mst2_qualified_family_policy WHERE singleton=1")))