querysub 0.358.0 → 0.359.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 +11 -0
- package/src/deployManager/components/MachineDetailPage.tsx +2 -2
- package/src/deployManager/components/ServiceDetailPage.tsx +13 -3
- package/src/deployManager/components/ServicesListPage.tsx +18 -6
- package/src/diagnostics/logs/IndexedLogs/IndexedLogs.ts +77 -75
- package/src/diagnostics/logs/IndexedLogs/LogViewer3.tsx +5 -0
- package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycles.tsx +14 -5
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isNode } from "socket-function/src/misc";
|
|
2
|
+
import os from "os";
|
|
2
3
|
import { fsExistsAsync, getSubFolder } from "../fs";
|
|
3
4
|
import fs from "fs";
|
|
4
5
|
import { blue, red, yellow } from "socket-function/src/formatting/logColors";
|
|
@@ -440,5 +441,15 @@ export const getArchivesLocal = cache((domain: string): Archives => {
|
|
|
440
441
|
archivesLocal.LOCAL_ARCHIVE_FOLDER = getSubFolder(domain).replaceAll("\\", "/");
|
|
441
442
|
}
|
|
442
443
|
|
|
444
|
+
return archivesLocal;
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
export const getArchivesHome = cache((domain: string): Archives => {
|
|
448
|
+
const archivesLocal = new ArchivesDisk();
|
|
449
|
+
|
|
450
|
+
if (isNode()) {
|
|
451
|
+
archivesLocal.LOCAL_ARCHIVE_FOLDER = os.homedir() + "/querysub/" + domain + "/";
|
|
452
|
+
}
|
|
453
|
+
|
|
443
454
|
return archivesLocal;
|
|
444
455
|
});
|
|
@@ -118,8 +118,8 @@ export class MachineDetailPage extends qreact.Component {
|
|
|
118
118
|
<div className={css.vbox(10)}>
|
|
119
119
|
{Object.entries(machine.info).map(([key, value]) => (
|
|
120
120
|
<div key={key} className={css.hbox(10).hsla(0, 0, 0, 0.1).pad2(10, 2)}>
|
|
121
|
-
<b>{key}:</b>
|
|
122
|
-
<ShowMore className={css.whiteSpace("pre-wrap")} maxHeight={
|
|
121
|
+
<b className={css.flexShrink0}>{key}:</b>
|
|
122
|
+
<ShowMore className={css.whiteSpace("pre-wrap")} maxHeight={80}>
|
|
123
123
|
{(() => {
|
|
124
124
|
if (typeof value === "object") {
|
|
125
125
|
return <div className={css.pad2(6, 2).hsla(0, 0, 0, 0.1).relative}>
|
|
@@ -157,9 +157,11 @@ export class ServiceDetailPage extends qreact.Component {
|
|
|
157
157
|
let index = nextIndexes.get(machineId) || 0;
|
|
158
158
|
nextIndexes.set(machineId, index + 1);
|
|
159
159
|
let machineInfo = controller.getMachineInfo(machineId);
|
|
160
|
+
let machineConfig = controller.getMachineConfig(machineId);
|
|
160
161
|
const serviceInfo = machineInfo?.services[selectedServiceId || ""];
|
|
161
162
|
const isMachineDead = machineInfo ? Date.now() - machineInfo.heartbeat > (MACHINE_RESYNC_INTERVAL * 4) : true;
|
|
162
163
|
const hasError = serviceInfo?.errorFromLastRun;
|
|
164
|
+
const isDisabled = machineConfig?.disabled || false;
|
|
163
165
|
|
|
164
166
|
return {
|
|
165
167
|
machineId,
|
|
@@ -167,11 +169,12 @@ export class ServiceDetailPage extends qreact.Component {
|
|
|
167
169
|
serviceInfo,
|
|
168
170
|
isMachineDead,
|
|
169
171
|
hasError,
|
|
172
|
+
isDisabled,
|
|
170
173
|
heartbeat: machineInfo?.heartbeat || 0,
|
|
171
174
|
index
|
|
172
175
|
};
|
|
173
176
|
});
|
|
174
|
-
sort(machineStatuses, x => (x.hasError ? 0 : x.isMachineDead ? 1 : 2) * 1000000 + x.heartbeat);
|
|
177
|
+
sort(machineStatuses, x => (x.isDisabled ? 3 : x.hasError ? 0 : x.isMachineDead ? 1 : 2) * 1000000 + x.heartbeat);
|
|
175
178
|
let now = Date.now();
|
|
176
179
|
|
|
177
180
|
let machines = (controller.getMachineList() || []).map(x => controller.getMachineInfo(x)).filter(isDefined);
|
|
@@ -253,11 +256,13 @@ export class ServiceDetailPage extends qreact.Component {
|
|
|
253
256
|
{configT.parameters.deploy && <div className={css.vbox(8).fillWidth}>
|
|
254
257
|
<h3>Deployed Machines ({config.machineIds.length})</h3>
|
|
255
258
|
<div className={css.vbox(4).fillWidth}>
|
|
256
|
-
{machineStatuses.map(({ machineId, machineInfo, serviceInfo, isMachineDead, hasError, index }) => {
|
|
259
|
+
{machineStatuses.map(({ machineId, machineInfo, serviceInfo, isMachineDead, hasError, isDisabled, index }) => {
|
|
257
260
|
if (!machineInfo) return <div key={machineId}>Loading {machineId}...</div>;
|
|
258
261
|
|
|
259
262
|
let backgroundColor = css.hsl(0, 0, 100); // Default: white
|
|
260
|
-
if (
|
|
263
|
+
if (isDisabled) {
|
|
264
|
+
backgroundColor = css.hsl(0, 0, 50); // Gray for disabled machines
|
|
265
|
+
} else if (hasError) {
|
|
261
266
|
backgroundColor = css.hsl(0, 70, 90); // Red-ish for errors
|
|
262
267
|
} else if (isMachineDead) {
|
|
263
268
|
backgroundColor = css.hsl(0, 0, 50); // Gray for dead machines
|
|
@@ -281,6 +286,11 @@ export class ServiceDetailPage extends qreact.Component {
|
|
|
281
286
|
{machineId} ({machineInfo.info["getExternalIP"]})
|
|
282
287
|
</div>
|
|
283
288
|
</div>
|
|
289
|
+
{isDisabled && (
|
|
290
|
+
<div className={css.colorhsl(0, 0, 30)}>
|
|
291
|
+
🚫 Machine Disabled
|
|
292
|
+
</div>
|
|
293
|
+
)}
|
|
284
294
|
{isMachineDead && (
|
|
285
295
|
<div className={css.colorhsl(0, 80, 50)}>
|
|
286
296
|
⚠️ Machine Dead
|
|
@@ -21,6 +21,7 @@ export class ServicesListPage extends qreact.Component {
|
|
|
21
21
|
render() {
|
|
22
22
|
let controller = MachineServiceController(SocketFunction.browserNodeId());
|
|
23
23
|
let serviceList = controller.getServiceList();
|
|
24
|
+
let machineConfigList = controller.getMachineConfigList();
|
|
24
25
|
|
|
25
26
|
if (!serviceList) return <div>Loading services...</div>;
|
|
26
27
|
|
|
@@ -28,6 +29,7 @@ export class ServicesListPage extends qreact.Component {
|
|
|
28
29
|
sort(services, x => -(x[1]?.info.lastUpdatedTime || Date.now()) - (x[1]?.parameters.deploy && (Number.MAX_SAFE_INTEGER / 2) || 0));
|
|
29
30
|
|
|
30
31
|
let getMachineInfo = cache((machineId: string) => controller.getMachineInfo(machineId));
|
|
32
|
+
let getMachineConfig = cache((machineId: string) => controller.getMachineConfig(machineId));
|
|
31
33
|
|
|
32
34
|
let keyCounts = new Map<string, number>();
|
|
33
35
|
for (let [serviceId, config] of services) {
|
|
@@ -75,24 +77,34 @@ export class ServicesListPage extends qreact.Component {
|
|
|
75
77
|
<div className={css.vbox(8)}>
|
|
76
78
|
{services.map(([serviceId, config]) => {
|
|
77
79
|
if (!config) return <div key={serviceId}>Config is broken? Missing value for service? Is the file corrupted?</div>;
|
|
78
|
-
|
|
80
|
+
|
|
81
|
+
let disabledMachines = config.machineIds.filter(machineId => {
|
|
82
|
+
let machineConfig = getMachineConfig(machineId);
|
|
83
|
+
return machineConfig?.disabled;
|
|
84
|
+
});
|
|
85
|
+
let enabledMachineIds = config.machineIds.filter(machineId => {
|
|
86
|
+
let machineConfig = getMachineConfig(machineId);
|
|
87
|
+
return !machineConfig?.disabled;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
let failingMachines = enabledMachineIds.filter(machineId => {
|
|
79
91
|
let machineInfo = getMachineInfo(machineId);
|
|
80
92
|
return machineInfo?.services[serviceId]?.errorFromLastRun;
|
|
81
93
|
});
|
|
82
|
-
let runningMachines =
|
|
94
|
+
let runningMachines = enabledMachineIds.filter(machineId => {
|
|
83
95
|
let machineInfo = getMachineInfo(machineId);
|
|
84
96
|
let serviceInfo = machineInfo?.services[serviceId];
|
|
85
97
|
return serviceInfo && !serviceInfo.errorFromLastRun;
|
|
86
98
|
});
|
|
87
|
-
let missingMachines =
|
|
99
|
+
let missingMachines = enabledMachineIds.filter(machineId => {
|
|
88
100
|
let machineInfo = getMachineInfo(machineId);
|
|
89
101
|
return !machineInfo?.services[serviceId];
|
|
90
102
|
});
|
|
91
|
-
let totalLaunches =
|
|
103
|
+
let totalLaunches = enabledMachineIds.reduce((acc, machineId) => {
|
|
92
104
|
let machineInfo = getMachineInfo(machineId);
|
|
93
105
|
return acc + (machineInfo?.services[serviceId]?.totalTimesLaunched || 0);
|
|
94
106
|
}, 0);
|
|
95
|
-
let unknown =
|
|
107
|
+
let unknown = enabledMachineIds.length - runningMachines.length - failingMachines.length - missingMachines.length;
|
|
96
108
|
let duplicateKey = (keyCounts.get(config.parameters.key || "") || 0) > 1;
|
|
97
109
|
return <div className={css.hbox(10)}>
|
|
98
110
|
<Anchor noStyles key={serviceId}
|
|
@@ -118,7 +130,7 @@ export class ServicesListPage extends qreact.Component {
|
|
|
118
130
|
{config.parameters.key}
|
|
119
131
|
</div>
|
|
120
132
|
<div>
|
|
121
|
-
{
|
|
133
|
+
{enabledMachineIds.length} configured {disabledMachines.length > 0 && `(+${disabledMachines.length} on disabled machines)`} {failingMachines.length > 0 && `(${failingMachines.length} failing)`} {missingMachines.length > 0 && `(${missingMachines.length} machine hasn't run service yet)`} {unknown > 0 && `(${unknown} unknown)`} • {totalLaunches} launches •
|
|
122
134
|
Deploy: {config.parameters.deploy ? "enabled" : "disabled"}
|
|
123
135
|
</div>
|
|
124
136
|
</div>
|
|
@@ -5,7 +5,7 @@ import { BufferIndex } from "./BufferIndex";
|
|
|
5
5
|
import { delay, runInParallel, runInSerial, runInfinitePoll } from "socket-function/src/batching";
|
|
6
6
|
import { IndexedLogResults, Reader, SearchParams, addReadToResults, createEmptyIndexedLogResults, INDEX_EXTENSION } from "./BufferIndexHelpers";
|
|
7
7
|
import { getDomain, isPublic } from "../../../config";
|
|
8
|
-
import { getArchivesLocal } from "../../../-a-archives/archivesDisk";
|
|
8
|
+
import { getArchivesHome, getArchivesLocal } from "../../../-a-archives/archivesDisk";
|
|
9
9
|
import { getArchivesBackblaze, getArchivesBackblazePrivateImmutable } from "../../../-a-archives/archivesBackBlaze";
|
|
10
10
|
import { getOwnThreadId } from "../../../-a-auth/certs";
|
|
11
11
|
import { ArchivesMemoryCacheStats, createArchivesMemoryCache } from "../../../-a-archives/archivesMemoryCache";
|
|
@@ -53,78 +53,6 @@ export class IndexedLogs<T> {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
private findCallbacks = new Map<string, (match: T) => void>();
|
|
57
|
-
private resultsCallbacks = new Map<string, (results: IndexedLogResults) => void>();
|
|
58
|
-
public async clientFind(config: {
|
|
59
|
-
params: SearchParams;
|
|
60
|
-
onResult: (match: T) => void;
|
|
61
|
-
onResults?: (results: IndexedLogResults) => void;
|
|
62
|
-
}): Promise<IndexedLogResults> {
|
|
63
|
-
let controller = IndexedLogShimController.nodes[SocketFunction.getBrowserNodeId()];
|
|
64
|
-
let findId = nextId();
|
|
65
|
-
let callback = (match: T) => {
|
|
66
|
-
config.onResult(match);
|
|
67
|
-
};
|
|
68
|
-
this.findCallbacks.set(findId, callback);
|
|
69
|
-
if (config.onResults) {
|
|
70
|
-
this.resultsCallbacks.set(findId, config.onResults);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
return await controller.find({
|
|
74
|
-
findId,
|
|
75
|
-
indexedLogsName: this.config.name,
|
|
76
|
-
params: config.params,
|
|
77
|
-
});
|
|
78
|
-
} finally {
|
|
79
|
-
// There's some trailing time after the controller call finishes when the results will be trickling back to us.
|
|
80
|
-
setTimeout(() => {
|
|
81
|
-
this.findCallbacks.delete(findId);
|
|
82
|
-
this.resultsCallbacks.delete(findId);
|
|
83
|
-
}, timeInMinute * 30);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
public clientCancelAllCallbacks() {
|
|
87
|
-
this.findCallbacks.clear();
|
|
88
|
-
this.resultsCallbacks.clear();
|
|
89
|
-
}
|
|
90
|
-
public async clientGetPaths(config: {
|
|
91
|
-
startTime: number;
|
|
92
|
-
endTime: number;
|
|
93
|
-
only?: "local" | "public";
|
|
94
|
-
}): Promise<TimeFilePathWithSize[]> {
|
|
95
|
-
let controller = IndexedLogShimController.nodes[SocketFunction.getBrowserNodeId()];
|
|
96
|
-
return await controller.getPaths({
|
|
97
|
-
indexedLogsName: this.config.name,
|
|
98
|
-
startTime: config.startTime,
|
|
99
|
-
endTime: config.endTime,
|
|
100
|
-
only: config.only,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
public onFindResult(config: {
|
|
104
|
-
findId: string;
|
|
105
|
-
result: unknown;
|
|
106
|
-
}) {
|
|
107
|
-
let callback = this.findCallbacks.get(config.findId);
|
|
108
|
-
if (!callback) throw new Error(`Find callback ${config.findId} not found`);
|
|
109
|
-
callback(config.result as T);
|
|
110
|
-
}
|
|
111
|
-
public async onResults(config: {
|
|
112
|
-
findId: string;
|
|
113
|
-
results: IndexedLogResults;
|
|
114
|
-
}): Promise<boolean> {
|
|
115
|
-
let callback = this.resultsCallbacks.get(config.findId);
|
|
116
|
-
if (!callback) throw new Error(`Results callback ${config.findId} not found`);
|
|
117
|
-
callback(config.results);
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public async clientForceMoveLogsToPublic() {
|
|
122
|
-
let controller = IndexedLogShimController.nodes[SocketFunction.getBrowserNodeId()];
|
|
123
|
-
await controller.forceMoveLogsToPublic({
|
|
124
|
-
indexedLogsName: this.config.name,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
56
|
private localLogsStats = {
|
|
129
57
|
cachedReads: 0,
|
|
130
58
|
uncachedReads: 0,
|
|
@@ -145,7 +73,7 @@ export class IndexedLogs<T> {
|
|
|
145
73
|
private fileSizeCache = new Map<string, number>();
|
|
146
74
|
|
|
147
75
|
private getLocalLogs = lazy((): Archives => {
|
|
148
|
-
let baseDisk =
|
|
76
|
+
let baseDisk = getArchivesHome(getDomain());
|
|
149
77
|
let archives = nestArchives("indexed-logs/" + this.config.name, baseDisk);
|
|
150
78
|
archives = createArchivesMemoryCache(archives, {
|
|
151
79
|
maxSize: 1024 * 1024 * 512,
|
|
@@ -158,7 +86,7 @@ export class IndexedLogs<T> {
|
|
|
158
86
|
return archives;
|
|
159
87
|
});
|
|
160
88
|
private getPublicLogs = lazy((): Archives => {
|
|
161
|
-
let basePublic: Archives =
|
|
89
|
+
let basePublic: Archives = getArchivesHome(getDomain());
|
|
162
90
|
// NOTE: The local disk is so fast that reading in 10 megabytes is nothing, And if we read in too small of a value, the overhead per read ends up making this take forever.
|
|
163
91
|
let extraReadSize = 1024 * 1024 * 10;
|
|
164
92
|
if (this.config.forceUsePublicLogs || isPublic()) {
|
|
@@ -547,6 +475,80 @@ export class IndexedLogs<T> {
|
|
|
547
475
|
}
|
|
548
476
|
|
|
549
477
|
|
|
478
|
+
// #region Client Calls
|
|
479
|
+
private findCallbacks = new Map<string, (match: T) => void>();
|
|
480
|
+
private resultsCallbacks = new Map<string, (results: IndexedLogResults) => void>();
|
|
481
|
+
public async clientFind(config: {
|
|
482
|
+
params: SearchParams;
|
|
483
|
+
onResult: (match: T) => void;
|
|
484
|
+
onResults?: (results: IndexedLogResults) => void;
|
|
485
|
+
}): Promise<IndexedLogResults> {
|
|
486
|
+
let controller = IndexedLogShimController.nodes[SocketFunction.getBrowserNodeId()];
|
|
487
|
+
let findId = nextId();
|
|
488
|
+
let callback = (match: T) => {
|
|
489
|
+
config.onResult(match);
|
|
490
|
+
};
|
|
491
|
+
this.findCallbacks.set(findId, callback);
|
|
492
|
+
if (config.onResults) {
|
|
493
|
+
this.resultsCallbacks.set(findId, config.onResults);
|
|
494
|
+
}
|
|
495
|
+
try {
|
|
496
|
+
return await controller.find({
|
|
497
|
+
findId,
|
|
498
|
+
indexedLogsName: this.config.name,
|
|
499
|
+
params: config.params,
|
|
500
|
+
});
|
|
501
|
+
} finally {
|
|
502
|
+
// There's some trailing time after the controller call finishes when the results will be trickling back to us.
|
|
503
|
+
setTimeout(() => {
|
|
504
|
+
this.findCallbacks.delete(findId);
|
|
505
|
+
this.resultsCallbacks.delete(findId);
|
|
506
|
+
}, timeInMinute * 30);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
public clientCancelAllCallbacks() {
|
|
510
|
+
this.findCallbacks.clear();
|
|
511
|
+
this.resultsCallbacks.clear();
|
|
512
|
+
}
|
|
513
|
+
public async clientGetPaths(config: {
|
|
514
|
+
startTime: number;
|
|
515
|
+
endTime: number;
|
|
516
|
+
only?: "local" | "public";
|
|
517
|
+
}): Promise<TimeFilePathWithSize[]> {
|
|
518
|
+
let controller = IndexedLogShimController.nodes[SocketFunction.getBrowserNodeId()];
|
|
519
|
+
return await controller.getPaths({
|
|
520
|
+
indexedLogsName: this.config.name,
|
|
521
|
+
startTime: config.startTime,
|
|
522
|
+
endTime: config.endTime,
|
|
523
|
+
only: config.only,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
public onFindResult(config: {
|
|
527
|
+
findId: string;
|
|
528
|
+
result: unknown;
|
|
529
|
+
}) {
|
|
530
|
+
let callback = this.findCallbacks.get(config.findId);
|
|
531
|
+
if (!callback) throw new Error(`Find callback ${config.findId} not found`);
|
|
532
|
+
callback(config.result as T);
|
|
533
|
+
}
|
|
534
|
+
public async onResults(config: {
|
|
535
|
+
findId: string;
|
|
536
|
+
results: IndexedLogResults;
|
|
537
|
+
}): Promise<boolean> {
|
|
538
|
+
let callback = this.resultsCallbacks.get(config.findId);
|
|
539
|
+
if (!callback) throw new Error(`Results callback ${config.findId} not found`);
|
|
540
|
+
callback(config.results);
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
public async clientForceMoveLogsToPublic() {
|
|
545
|
+
let controller = IndexedLogShimController.nodes[SocketFunction.getBrowserNodeId()];
|
|
546
|
+
await controller.forceMoveLogsToPublic({
|
|
547
|
+
indexedLogsName: this.config.name,
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
// #endregion
|
|
551
|
+
|
|
550
552
|
|
|
551
553
|
// TEST functions
|
|
552
554
|
public async TEST_flushNow() {
|
|
@@ -854,6 +854,11 @@ export class LogViewer3 extends qreact.Component {
|
|
|
854
854
|
>
|
|
855
855
|
{savedPathsURL.value ? `Clear Frozen Files (${this.getPaths().length})` : `Freeze Files (${this.state.paths.length})`}
|
|
856
856
|
</Button>
|
|
857
|
+
{!savedPathsURL.value && (
|
|
858
|
+
<div className={css.pad2(8, 4).hsl(40, 60, 50).colorhsl(40, 0, 100)}>
|
|
859
|
+
Files frozen in memory. Click Preview Files to refresh.
|
|
860
|
+
</div>
|
|
861
|
+
)}
|
|
857
862
|
{(() => {
|
|
858
863
|
if (!savedPathsURL.value) return undefined;
|
|
859
864
|
const paths = this.getPaths();
|
|
@@ -19,12 +19,11 @@ IMPORTANT! Now I am properly calling shutdown, so none of the streamed logs shou
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- This is annoying, but it would be very useful. I think the apply loop can probably figure it out. We should probably ask the AI to do it. I'm sure it'll fuck it up, but it'll give us a start at least. And we can also just tell it, okay, find the actual code that we're going to need to change, but not change it, and just keep and maybe even have it put a comment there. And then we just keep doing that until we're absolutely certain that we found every place that we need to change to make this work. And then the AI might be able to help with the refactor.
|
|
24
|
-
3) Start the servers again, and deploy all of our code
|
|
22
|
+
OH! The archives have to be put in the home folder. They aren't?
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
|
|
25
|
+
Hmm... why are not enough logs appearing?
|
|
26
|
+
- We only have logs for server.ts? Wtf?
|
|
28
27
|
|
|
29
28
|
2.0) SUPPORT reading pending from multiple servers
|
|
30
29
|
- The main controller has to find a node on each other machine, and call it. Only one node per machine though, so it shouldn't be too difficult.
|
|
@@ -35,6 +34,14 @@ IMPORTANT! Now I am properly calling shutdown, so none of the streamed logs shou
|
|
|
35
34
|
2) Add a UI toggle to read public logs (only shows up on a non-public server though, as otherwise it wouldn't make sense)
|
|
36
35
|
- Basically, just changes the code we're reading from multiple servers to select public servers instead, and then, of course, skip ourselves.
|
|
37
36
|
|
|
37
|
+
BUG: UGH... live logs for the remote server isn't working...
|
|
38
|
+
"new non-local WATCH"
|
|
39
|
+
- UGH... it being pending logs is annoying, as that's hard to debug locally...
|
|
40
|
+
AH! Why do we have so few logs?
|
|
41
|
+
|
|
42
|
+
2) Create lot of remote server logs
|
|
43
|
+
- Via our refresh loop
|
|
44
|
+
|
|
38
45
|
3) Verify true remote reads are reasonable fast
|
|
39
46
|
|
|
40
47
|
3) Deploy service for movelogs
|
|
@@ -63,10 +70,12 @@ Rewrite error notification code
|
|
|
63
70
|
AND, the only watcher will be the watcher service. You can't get recent errors, or any errors, without going through one of those
|
|
64
71
|
NO dev errors. They are usually red-herrings anyways... and we should just be using public servers for regular usage
|
|
65
72
|
- And we still have dev logs we can check if to see if an error happened locally
|
|
73
|
+
ALSO owns the discord messaging code
|
|
66
74
|
|
|
67
75
|
|
|
68
76
|
|
|
69
77
|
Remove all old LogViewer/FastArchiveAppendable code
|
|
78
|
+
- Make sure to find all links and update them as well
|
|
70
79
|
|
|
71
80
|
|
|
72
81
|
0) Add LZ4 compression to socket-function by default
|