querysub 0.395.0 → 0.397.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/-a-archives/archivesDisk.ts +2 -2
- package/src/-c-identity/IdentityController.ts +19 -1
- package/src/0-path-value-core/pathValueCore.ts +8 -8
- package/src/3-path-functions/pathFunctionLoader.ts +2 -2
- package/src/deployManager/machineApplyMainCode.ts +1 -1
- package/src/diagnostics/logs/IndexedLogs/LogViewer3.tsx +3 -4
- package/src/diagnostics/logs/IndexedLogs/bufferSearchFindMatcher.ts +1 -0
- package/src/diagnostics/logs/errorNotifications2/ErrorNotificationPage.tsx +3 -1
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryEditor.tsx +358 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryReadMode.tsx +149 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCyclePage.tsx +33 -705
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleRenderer.tsx +291 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/NestedLifeCycleInfo.tsx +151 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleSearch.tsx +61 -34
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycles.tsx +3 -0
- package/src/diagnostics/misc-pages/ArchiveViewer.tsx +4 -3
- package/src/diagnostics/misc-pages/ArchiveViewerTree.tsx +6 -3
- package/src/library-components/StartEllipsis.tsx +1 -1
- package/tempnotes.txt +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Querysub } from "../../../4-querysub/QuerysubController";
|
|
2
2
|
import { getTimeRange } from "../TimeRangeSelector";
|
|
3
|
-
import { URLParam } from "../../../library-components/URLParam";
|
|
4
3
|
import { throttleFunction, sort } from "socket-function/src/misc";
|
|
5
4
|
import { getLoggers2Async, LogDatum } from "../diskLogger";
|
|
6
5
|
import { IndexedLogResults, createEmptyIndexedLogResults, mergeIndexedLogResults } from "../IndexedLogs/BufferIndexHelpers";
|
|
@@ -11,8 +10,7 @@ import { createMatchesPatternCached } from "../IndexedLogs/bufferSearchFindMatch
|
|
|
11
10
|
import { getPathStr } from "../../../path";
|
|
12
11
|
import { LifeCycle, LifeCycleEntry, LifeCyclesController } from "./lifeCycles";
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
export let additionalSearchURL = new URLParam("lifecyclesearch", "");
|
|
13
|
+
const PHASE_2_FACTOR = 100;
|
|
16
14
|
|
|
17
15
|
type LifecycleInstance = {
|
|
18
16
|
key: string;
|
|
@@ -23,8 +21,8 @@ type LifecycleInstance = {
|
|
|
23
21
|
}[];
|
|
24
22
|
isComplete?: boolean;
|
|
25
23
|
isTruncated?: boolean;
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
isMissingStart?: boolean;
|
|
25
|
+
isMissingEnd?: boolean;
|
|
28
26
|
startTime: number;
|
|
29
27
|
endTime?: number;
|
|
30
28
|
};
|
|
@@ -41,12 +39,40 @@ export function createLifeCycleSearch(
|
|
|
41
39
|
phase2Results: LogDatum[];
|
|
42
40
|
phase2Stats: IndexedLogResults | undefined;
|
|
43
41
|
phase2Searching: boolean;
|
|
42
|
+
phase2HitLimit: boolean;
|
|
44
43
|
lifecycleInstances: LifecycleInstance[];
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
46
|
) {
|
|
48
47
|
let searchSequenceNumber = 0;
|
|
49
48
|
|
|
49
|
+
let clearSearchingFlags = () => {
|
|
50
|
+
context.state.phase1Searching = false;
|
|
51
|
+
context.state.phase2Searching = false;
|
|
52
|
+
context.state.phase2HitLimit = false;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
let resetAllSearchState = (lifeCycleId?: string) => {
|
|
56
|
+
context.state.searchingLifeCycleId = lifeCycleId;
|
|
57
|
+
context.state.lifecycleInstances = [];
|
|
58
|
+
resetPhase1State();
|
|
59
|
+
resetPhase2State();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
let resetPhase1State = () => {
|
|
63
|
+
context.state.phase1Searching = true;
|
|
64
|
+
context.state.phase1Results = [];
|
|
65
|
+
context.state.phase1InvalidResults = [];
|
|
66
|
+
context.state.phase1Stats = undefined;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
let resetPhase2State = () => {
|
|
70
|
+
context.state.phase2Searching = true;
|
|
71
|
+
context.state.phase2Results = [];
|
|
72
|
+
context.state.phase2Stats = undefined;
|
|
73
|
+
context.state.phase2HitLimit = false;
|
|
74
|
+
};
|
|
75
|
+
|
|
50
76
|
let cancel = async () => {
|
|
51
77
|
searchSequenceNumber++;
|
|
52
78
|
let loggers = await getLoggers2Async();
|
|
@@ -54,14 +80,18 @@ export function createLifeCycleSearch(
|
|
|
54
80
|
logger.clientCancelAllCallbacks();
|
|
55
81
|
}
|
|
56
82
|
Querysub.commitLocal(() => {
|
|
57
|
-
|
|
58
|
-
context.state.phase2Searching = false;
|
|
83
|
+
clearSearchingFlags();
|
|
59
84
|
});
|
|
60
85
|
};
|
|
61
86
|
|
|
62
87
|
// Entry point for lifecycle search. Currently only supports "find all" mode by passing empty seedDatums.
|
|
63
88
|
// Future: Will be parameterized to accept specific log datums from other pages.
|
|
64
|
-
let searchLifeCycle = async (
|
|
89
|
+
let searchLifeCycle = async (params: {
|
|
90
|
+
lifeCycleId: string;
|
|
91
|
+
additionalSearch: string;
|
|
92
|
+
limit: number;
|
|
93
|
+
}) => {
|
|
94
|
+
let { lifeCycleId, additionalSearch, limit } = params;
|
|
65
95
|
let lifeCycles = await context.controller.getLifeCycles.promise();
|
|
66
96
|
if (!lifeCycles) return;
|
|
67
97
|
|
|
@@ -75,13 +105,7 @@ export function createLifeCycleSearch(
|
|
|
75
105
|
await cancel();
|
|
76
106
|
|
|
77
107
|
Querysub.commitLocal(() => {
|
|
78
|
-
|
|
79
|
-
context.state.phase1Results = [];
|
|
80
|
-
context.state.phase1InvalidResults = [];
|
|
81
|
-
context.state.phase1Stats = undefined;
|
|
82
|
-
context.state.phase2Results = [];
|
|
83
|
-
context.state.phase2Stats = undefined;
|
|
84
|
-
context.state.lifecycleInstances = [];
|
|
108
|
+
resetAllSearchState(lifeCycleId);
|
|
85
109
|
});
|
|
86
110
|
|
|
87
111
|
searchSequenceNumber++;
|
|
@@ -90,6 +114,8 @@ export function createLifeCycleSearch(
|
|
|
90
114
|
let phase1Results = await searchPhase1({
|
|
91
115
|
lifeCycle,
|
|
92
116
|
currentSequenceNumber,
|
|
117
|
+
additionalSearch,
|
|
118
|
+
limit,
|
|
93
119
|
});
|
|
94
120
|
|
|
95
121
|
if (searchSequenceNumber !== currentSequenceNumber) return;
|
|
@@ -102,6 +128,7 @@ export function createLifeCycleSearch(
|
|
|
102
128
|
lifeCycle,
|
|
103
129
|
phase1Results,
|
|
104
130
|
currentSequenceNumber,
|
|
131
|
+
limit,
|
|
105
132
|
});
|
|
106
133
|
|
|
107
134
|
if (searchSequenceNumber !== currentSequenceNumber) return;
|
|
@@ -123,8 +150,10 @@ export function createLifeCycleSearch(
|
|
|
123
150
|
let searchPhase1 = async (params: {
|
|
124
151
|
lifeCycle: LifeCycle;
|
|
125
152
|
currentSequenceNumber: number;
|
|
153
|
+
additionalSearch: string;
|
|
154
|
+
limit: number;
|
|
126
155
|
}) => {
|
|
127
|
-
let { lifeCycle, currentSequenceNumber } = params;
|
|
156
|
+
let { lifeCycle, currentSequenceNumber, additionalSearch, limit } = params;
|
|
128
157
|
let startEntries = lifeCycle.entries.filter(e => e.isStart);
|
|
129
158
|
|
|
130
159
|
if (startEntries.length === 0) {
|
|
@@ -132,14 +161,10 @@ export function createLifeCycleSearch(
|
|
|
132
161
|
}
|
|
133
162
|
|
|
134
163
|
Querysub.commitLocal(() => {
|
|
135
|
-
|
|
136
|
-
context.state.phase1Results = [];
|
|
137
|
-
context.state.phase1InvalidResults = [];
|
|
138
|
-
context.state.phase1Stats = undefined;
|
|
164
|
+
resetPhase1State();
|
|
139
165
|
});
|
|
140
166
|
|
|
141
167
|
let searchQuery = startEntries.map(entry => entry.matchPattern).join("|");
|
|
142
|
-
let additionalSearch = additionalSearchURL.value.trim();
|
|
143
168
|
if (additionalSearch) {
|
|
144
169
|
searchQuery = searchQuery + "&" + additionalSearch;
|
|
145
170
|
}
|
|
@@ -201,7 +226,7 @@ export function createLifeCycleSearch(
|
|
|
201
226
|
params: {
|
|
202
227
|
startTime: range.startTime,
|
|
203
228
|
endTime: range.endTime,
|
|
204
|
-
limit:
|
|
229
|
+
limit: limit,
|
|
205
230
|
findBuffer: searchBuffer,
|
|
206
231
|
searchFromStart: range.searchFromStart,
|
|
207
232
|
},
|
|
@@ -272,17 +297,16 @@ export function createLifeCycleSearch(
|
|
|
272
297
|
lifeCycle: LifeCycle;
|
|
273
298
|
phase1Results: LogDatum[];
|
|
274
299
|
currentSequenceNumber: number;
|
|
300
|
+
limit: number;
|
|
275
301
|
}): Promise<{ results: LogDatum[]; hitLimit: boolean }> => {
|
|
276
|
-
let { lifeCycle, phase1Results, currentSequenceNumber } = params;
|
|
302
|
+
let { lifeCycle, phase1Results, currentSequenceNumber, limit } = params;
|
|
277
303
|
|
|
278
304
|
if (phase1Results.length === 0) {
|
|
279
305
|
return { results: [], hitLimit: false };
|
|
280
306
|
}
|
|
281
307
|
|
|
282
308
|
Querysub.commitLocal(() => {
|
|
283
|
-
|
|
284
|
-
context.state.phase2Results = [];
|
|
285
|
-
context.state.phase2Stats = undefined;
|
|
309
|
+
resetPhase2State();
|
|
286
310
|
});
|
|
287
311
|
|
|
288
312
|
let allResults: LogDatum[] = [];
|
|
@@ -391,7 +415,7 @@ export function createLifeCycleSearch(
|
|
|
391
415
|
|
|
392
416
|
let results: LogDatum[] = [];
|
|
393
417
|
let done = false;
|
|
394
|
-
let searchLimit =
|
|
418
|
+
let searchLimit = Math.ceil(limit * lifeCycle.entries.length * PHASE_2_FACTOR);
|
|
395
419
|
let result = await errorToUndefined(logger.clientFind({
|
|
396
420
|
params: {
|
|
397
421
|
startTime: range.startTime,
|
|
@@ -426,6 +450,7 @@ export function createLifeCycleSearch(
|
|
|
426
450
|
Querysub.commitLocal(() => {
|
|
427
451
|
context.state.phase2Results = allResults;
|
|
428
452
|
context.state.phase2Searching = false;
|
|
453
|
+
context.state.phase2HitLimit = anyHitLimit;
|
|
429
454
|
});
|
|
430
455
|
|
|
431
456
|
return { results: allResults, hitLimit: anyHitLimit };
|
|
@@ -463,7 +488,7 @@ export function createLifeCycleSearch(
|
|
|
463
488
|
keyValuePairs.push({ key: keyConfig.ourKey, value });
|
|
464
489
|
}
|
|
465
490
|
if (!hasAllKeys) continue;
|
|
466
|
-
let
|
|
491
|
+
let keyHash = getPathStr(keyValuePairs.flatMap(kv => [kv.key, String(kv.value)]));
|
|
467
492
|
|
|
468
493
|
let matchStr = String(datum.param0);
|
|
469
494
|
let matchBuffer = Buffer.from(matchStr, "utf8");
|
|
@@ -472,10 +497,10 @@ export function createLifeCycleSearch(
|
|
|
472
497
|
let matcher = createMatchesPatternCached(entry.matchPattern);
|
|
473
498
|
if (!matcher(matchBuffer)) continue;
|
|
474
499
|
|
|
475
|
-
let instanceList = instancesByKey.get(
|
|
500
|
+
let instanceList = instancesByKey.get(keyHash);
|
|
476
501
|
if (!instanceList) {
|
|
477
502
|
instanceList = [];
|
|
478
|
-
instancesByKey.set(
|
|
503
|
+
instancesByKey.set(keyHash, instanceList);
|
|
479
504
|
}
|
|
480
505
|
|
|
481
506
|
let currentInstance = maybeUndefined(instanceList[instanceList.length - 1]);
|
|
@@ -506,8 +531,7 @@ export function createLifeCycleSearch(
|
|
|
506
531
|
key: keyFields.map(k => k.ourKey).join(","),
|
|
507
532
|
keys: keyValuePairs,
|
|
508
533
|
entries: [{ datum, matchPattern: entry.matchPattern }],
|
|
509
|
-
|
|
510
|
-
warningMessage: "End entry without matching start",
|
|
534
|
+
isMissingStart: true,
|
|
511
535
|
startTime: 0,
|
|
512
536
|
});
|
|
513
537
|
}
|
|
@@ -519,8 +543,7 @@ export function createLifeCycleSearch(
|
|
|
519
543
|
key: keyFields.map(k => k.ourKey).join(","),
|
|
520
544
|
keys: keyValuePairs,
|
|
521
545
|
entries: [{ datum, matchPattern: entry.matchPattern }],
|
|
522
|
-
|
|
523
|
-
warningMessage: "Entry without matching start",
|
|
546
|
+
isMissingStart: true,
|
|
524
547
|
startTime: 0,
|
|
525
548
|
});
|
|
526
549
|
}
|
|
@@ -534,6 +557,9 @@ export function createLifeCycleSearch(
|
|
|
534
557
|
if (instance.entries.length > 0) {
|
|
535
558
|
instance.startTime = instance.entries[0].datum.time;
|
|
536
559
|
}
|
|
560
|
+
if (!instance.isComplete && !instance.isTruncated && !instance.isMissingStart) {
|
|
561
|
+
instance.isMissingEnd = true;
|
|
562
|
+
}
|
|
537
563
|
}
|
|
538
564
|
|
|
539
565
|
sort(allInstances, x => x.startTime);
|
|
@@ -547,6 +573,7 @@ export function createLifeCycleSearch(
|
|
|
547
573
|
searchPhase2,
|
|
548
574
|
groupLifecycleResults,
|
|
549
575
|
cancel,
|
|
576
|
+
resetAllSearchState,
|
|
550
577
|
};
|
|
551
578
|
}
|
|
552
579
|
|
|
@@ -30,12 +30,15 @@ export type LifeCycleEntry = {
|
|
|
30
30
|
ourKey: string;
|
|
31
31
|
// Defaults to the same key, which is usually the case
|
|
32
32
|
startKey?: string;
|
|
33
|
+
|
|
34
|
+
aliases?: string[];
|
|
33
35
|
}[];
|
|
34
36
|
|
|
35
37
|
// All of the special variables, which are marked. The title defaults to the key, but can be overriden for the purposes of adding notes.
|
|
36
38
|
variables: {
|
|
37
39
|
[key: string]: {
|
|
38
40
|
title?: string;
|
|
41
|
+
aliases?: string[];
|
|
39
42
|
};
|
|
40
43
|
};
|
|
41
44
|
};
|
|
@@ -190,7 +190,8 @@ export class ArchiveViewer extends qreact.Component {
|
|
|
190
190
|
this.state.parsedValues = atomicObjectWrite({});
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
// NOTE: I don't understand why we were grouping this. Doing a thousand calls is not that slow, there's not that much overhead. And we want to have small groups, that way, we get more progress.
|
|
194
|
+
const MAX_FILES = 1;
|
|
194
195
|
const MAX_SIZE = 500 * 1024 * 1024;
|
|
195
196
|
let bufferObjs: { path: string; buffer: Buffer }[] = [];
|
|
196
197
|
let newParsedValues: { [path: string]: PathValue[] } = {};
|
|
@@ -248,7 +249,7 @@ export class ArchiveViewer extends qreact.Component {
|
|
|
248
249
|
this.state.progress.filesParsed.max = remainingFiles.size + bufferObjs.length;
|
|
249
250
|
});
|
|
250
251
|
|
|
251
|
-
|
|
252
|
+
await Promise.all(fileGroups.map(async group => {
|
|
252
253
|
//let time = Date.now();
|
|
253
254
|
let newBuffers = await controller.getRawValueFiles(group.file, {
|
|
254
255
|
// 1) Allows viewing old archives
|
|
@@ -276,7 +277,7 @@ export class ArchiveViewer extends qreact.Component {
|
|
|
276
277
|
this.state.progress.filesDownloaded.value += group.file.length;
|
|
277
278
|
this.state.progress.bytesDownloaded += newBuffers.reduce((sum, buffer) => sum + (buffer?.buffer.byteLength || 0), 0);
|
|
278
279
|
});
|
|
279
|
-
}
|
|
280
|
+
}));
|
|
280
281
|
Querysub.commitLocal(() => {
|
|
281
282
|
this.state.progress.filesDownloaded.endTime = Date.now();
|
|
282
283
|
});
|
|
@@ -82,6 +82,9 @@ export class ArchiveViewerTree extends qreact.Component<{
|
|
|
82
82
|
if (scaleType === "size") {
|
|
83
83
|
total = node.totalSizeEstimate;
|
|
84
84
|
}
|
|
85
|
+
if (node.values.length === 1 && total > 1000 * 1000 * 1000) {
|
|
86
|
+
debugger;
|
|
87
|
+
}
|
|
85
88
|
countInfo += `(${formatNumber(node.values.length)} /// ${sumFormatter(total)}) `;
|
|
86
89
|
} else {
|
|
87
90
|
countInfo += `(${formatNumber(node.values.length)}) `;
|
|
@@ -395,7 +398,7 @@ export class ArchiveViewerTree extends qreact.Component<{
|
|
|
395
398
|
<div class={css.hbox(20)}>
|
|
396
399
|
<ButtonSelector<typeof archiveTreeScale.value>
|
|
397
400
|
options={[
|
|
398
|
-
{ title: this.props.valueLabel || "
|
|
401
|
+
{ title: this.props.valueLabel || "Size", value: "size" },
|
|
399
402
|
{ title: "Datum Count", value: "count" },
|
|
400
403
|
{ title: "Equal", value: "equal" },
|
|
401
404
|
]}
|
|
@@ -516,11 +519,11 @@ function treeifyValues(values: PathValue[], config: {
|
|
|
516
519
|
return node;
|
|
517
520
|
}
|
|
518
521
|
function estimateSize(value: PathValue) {
|
|
519
|
-
return
|
|
522
|
+
//return 1;
|
|
520
523
|
// if (config.sizeValueEstimateHack) {
|
|
521
524
|
// return Number(value.value) || 1;
|
|
522
525
|
// }
|
|
523
|
-
|
|
526
|
+
return getSingleSizeEstimate(value);
|
|
524
527
|
}
|
|
525
528
|
|
|
526
529
|
for (let value of values) {
|
|
@@ -6,7 +6,7 @@ export class StartEllipsis extends qreact.Component<{
|
|
|
6
6
|
}> {
|
|
7
7
|
render() {
|
|
8
8
|
return <div className={css.relative.maxWidth(this.props.maxWidth).overflowHidden.whiteSpace("nowrap").direction("rtl")}>
|
|
9
|
-
<span className={css.relative.direction("ltr")}>{this.props.children}</span>
|
|
9
|
+
<span className={css.relative.direction("ltr").unicodeBidi("isolate")}>{this.props.children}</span>
|
|
10
10
|
<span className={css.absolute.left(`calc((100% - ${this.props.maxWidth}px) * -10000)`).top(0).height("100%").width(30).background("linear-gradient(to right, white, transparent)").pointerEvents("none")}></span>
|
|
11
11
|
</div>;
|
|
12
12
|
}
|
package/tempnotes.txt
ADDED
|
File without changes
|