Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,28 @@ fn timed(latencies: &mut BTreeMap<&'static str, Vec<f64>>, name: &'static str, r
latencies.entry(name).or_default().push(started.elapsed().as_secs_f64() * 1000.0);
}

/// A chat tab's create validates the tabs it changed, not every tab of its pane: the pane's new order
/// (`SetTabOrder`) moves positions only, which its set and contiguous-position checks cover, as a workspace
/// order change already does. Checking every tab took about 5 queries per tab of the pane under the registry
/// lock, which a person's next click waits on (this file's first test).
#[test]
fn a_chat_tab_create_validates_only_the_tabs_it_changed() {
use std::sync::atomic::Ordering::Relaxed;
let session = Session::new("chat-tab-validates");
let mux = session.open();
let sidebar = sidebar(&mux);
let workspace = workspace_slot(&mux, &sidebar.loose[0]);
for index in 0..30 {
open_chat_tab(&mux, workspace, format!("before-{index}"));
}
let before = crate::workspace_registry::resource_store::TABS_VALIDATED.load(Relaxed);
open_chat_tab(&mux, workspace, "the-person".into());
let validated =
crate::workspace_registry::resource_store::TABS_VALIDATED.load(Relaxed) - before;
mux.shutdown();
assert!(validated <= 4, "one chat tab create in a 31-tab pane validated {validated} tabs");
}

#[test]
fn a_persons_requests_answer_while_busy_sessions_saturate_the_registry() {
let session = Session::new("person-request-latency");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4248,9 +4248,12 @@ fn validate_touched_resource_invariants(
&mut browsers,
)?;
}
ResourceChange::SetTabOrder { pane_id, tab_ids } => {
// An order change writes only the pane's tabs' positions: the set (set_resource_tab_order) and the
// contiguous positions (below) are its invariants, so it touches no tab's own rows, as
// `SetWorkspaceOrder` above. Validating every tab of the pane per create cost O(tabs in the pane):
// about 5 queries per tab, under the registry lock a person's next click waits on.
ResourceChange::SetTabOrder { pane_id, .. } => {
panes.insert(pane_id.to_string());
tabs.extend(tab_ids.iter().map(ToString::to_string));
}
ResourceChange::UpsertTerminal { public_id, .. }
| ResourceChange::TombstoneTerminal { public_id, .. } => {
Expand Down Expand Up @@ -4579,7 +4582,15 @@ fn validate_touched_pane(transaction: &Transaction<'_>, pane_id: &str) -> anyhow
Ok(())
}

/// Tabs [`validate_touched_tab`] checked in this test process (nextest runs each test alone): a commit's
/// validation must be O(changed), never O(tabs in the pane).
#[cfg(test)]
pub(crate) static TABS_VALIDATED: std::sync::atomic::AtomicU64 =
std::sync::atomic::AtomicU64::new(0);

fn validate_touched_tab(transaction: &Transaction<'_>, tab_id: &str) -> anyhow::Result<()> {
#[cfg(test)]
TABS_VALIDATED.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let stored = transaction
.query_row(
"SELECT pane_id, content_kind, content_id, deleted_revision
Expand Down
Loading