Show the row count while the load is still waiting on it
X-Row-Count is exact but travels with the response headers, and in grain mode the server aggregates the whole table before sending any -- so the number appeared just as the fifteen-second wait ended, which is no use to anyone watching it. The forecast table's own count goes up first instead, from the same table-info the status bar already reads, and the exact figure replaces it when the headers arrive. The count query is deliberately not awaited: it scans the whole table, and the load must not wait on a progress message. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9753846d34
commit
1a0a9db8d0
@ -57,10 +57,15 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [largeDataset, setLargeDataset] = useState(false)
|
||||
const [loadProgress, setLoadProgress] = useState(null) // { received, total }
|
||||
// Rows the server says it is sending, from X-Row-Count. Known as soon as the
|
||||
// headers land, well before the body has been read, so the wait can say what
|
||||
// it is waiting for -- on this data the row count is the wait (see CLAUDE.md,
|
||||
// "Load time is dominated by row count").
|
||||
// Rows the load is waiting on, so the wait can say what it is waiting for --
|
||||
// on this data the row count is the wait (see CLAUDE.md, "Load time is
|
||||
// dominated by row count").
|
||||
//
|
||||
// Filled twice. X-Row-Count is exact but arrives with the response headers,
|
||||
// and in grain mode the server aggregates before sending any: the number
|
||||
// turned up just as the wait ended. So the forecast table's own count goes in
|
||||
// first, from the same table-info the status bar reads, and the exact figure
|
||||
// replaces it when the headers land.
|
||||
const [loadRows, setLoadRows] = useState(null)
|
||||
const [msg, setMsg] = useState(null)
|
||||
|
||||
@ -646,7 +651,7 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
if (!r.ok) { const { error } = await r.json(); throw new Error(error || 'Failed to load data') }
|
||||
const rowCount = parseInt(r.headers.get('X-Row-Count') || '0')
|
||||
const total = parseInt(r.headers.get('Content-Length') || '0') || null
|
||||
setLoadRows(rowCount || null)
|
||||
if (rowCount) setLoadRows(rowCount)
|
||||
const reader = r.body.getReader()
|
||||
const chunks = []
|
||||
let received = 0
|
||||
@ -684,6 +689,12 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
setLargeDataset(false)
|
||||
setLoadProgress(null)
|
||||
setLoadRows(null)
|
||||
// deliberately not awaited: it is a count over the whole forecast table and
|
||||
// the load must not wait on it
|
||||
fetch(`/api/versions/${vid}/table-info`)
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(info => { if (info?.rows && initIdRef.current === myId) setLoadRows(n => n ?? info.rows) })
|
||||
.catch(() => {})
|
||||
setSlices([])
|
||||
setExpandDepth(null)
|
||||
adoptSplit([], 0)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user