Add id to streaming comparison

This avoids a bug where comparisons could potentially overlap if the
user opens a new comparison while the previous one has not yet finished
loading.
This commit is contained in:
Koen Vlaswinkel
2024-10-22 15:37:35 +02:00
parent a69ef15594
commit 510a269dde
3 changed files with 25 additions and 0 deletions

View File

@@ -424,6 +424,8 @@ export type InterpretedQueryCompareResult = {
export interface StreamingComparisonSetupMessage { export interface StreamingComparisonSetupMessage {
readonly t: "streamingComparisonSetup"; readonly t: "streamingComparisonSetup";
// The id of this streaming comparison
readonly id: string;
readonly currentResultSetName: string; readonly currentResultSetName: string;
readonly message: string | undefined; readonly message: string | undefined;
// The from and to fields will only contain a chunk of the results // The from and to fields will only contain a chunk of the results
@@ -432,12 +434,14 @@ export interface StreamingComparisonSetupMessage {
interface StreamingComparisonAddResultsMessage { interface StreamingComparisonAddResultsMessage {
readonly t: "streamingComparisonAddResults"; readonly t: "streamingComparisonAddResults";
readonly id: string;
// The from and to fields will only contain a chunk of the results // The from and to fields will only contain a chunk of the results
readonly result: QueryCompareResult; readonly result: QueryCompareResult;
} }
interface StreamingComparisonCompleteMessage { interface StreamingComparisonCompleteMessage {
readonly t: "streamingComparisonComplete"; readonly t: "streamingComparisonComplete";
readonly id: string;
} }
/** /**

View File

@@ -34,6 +34,7 @@ import {
} from "./result-set-names"; } from "./result-set-names";
import { compareInterpretedResults } from "./interpreted-results"; import { compareInterpretedResults } from "./interpreted-results";
import { isCanary } from "../config"; import { isCanary } from "../config";
import { nanoid } from "nanoid";
interface ComparePair { interface ComparePair {
from: CompletedLocalQueryInfo; from: CompletedLocalQueryInfo;
@@ -206,6 +207,8 @@ export class CompareView extends AbstractWebview<
return; return;
} }
const id = nanoid();
// Streaming itself is implemented like this: // Streaming itself is implemented like this:
// - 1 setup message which contains the first 1,000 results // - 1 setup message which contains the first 1,000 results
// - n "add results" messages which contain 1,000 results each // - n "add results" messages which contain 1,000 results each
@@ -213,6 +216,7 @@ export class CompareView extends AbstractWebview<
await this.postMessage({ await this.postMessage({
t: "streamingComparisonSetup", t: "streamingComparisonSetup",
id,
result: this.chunkResults(result, 0, 1000), result: this.chunkResults(result, 0, 1000),
currentResultSetName, currentResultSetName,
message, message,
@@ -226,12 +230,14 @@ export class CompareView extends AbstractWebview<
await this.postMessage({ await this.postMessage({
t: "streamingComparisonAddResults", t: "streamingComparisonAddResults",
id,
result: chunk, result: chunk,
}); });
} }
await this.postMessage({ await this.postMessage({
t: "streamingComparisonComplete", t: "streamingComparisonComplete",
id,
}); });
} }

View File

@@ -74,6 +74,13 @@ export function Compare(_: Record<string, never>): React.JSX.Element {
break; break;
} }
if (prev.id !== msg.id) {
console.warn(
'Received "streamingComparisonAddResults" with different id, ignoring',
);
break;
}
let result: QueryCompareResult; let result: QueryCompareResult;
switch (prev.result.kind) { switch (prev.result.kind) {
case "raw": case "raw":
@@ -121,6 +128,14 @@ export function Compare(_: Record<string, never>): React.JSX.Element {
setComparison(null); setComparison(null);
break; break;
} }
if (streamingComparisonRef.current.id !== msg.id) {
console.warn(
'Received "streamingComparisonComplete" with different id, ignoring',
);
break;
}
setComparison({ setComparison({
...streamingComparisonRef.current, ...streamingComparisonRef.current,
t: "setComparisons", t: "setComparisons",