querysub 0.42.0 → 0.43.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -31,6 +31,7 @@ import { decodeNodeId, encodeNodeId, getMachineId } from "../../-a-auth/certs";
31
31
  import { Button } from "../../library-components/Button";
32
32
  import { TimeRangeSelector } from "../../library-components/TimeRangeSelector";
33
33
  import { BrowserLargeFileCache, cacheCalls } from "./BrowserLargeFileCache";
34
+ import { Zip } from "../../zip";
34
35
 
35
36
  // TODO: Realtime log mode, by reading from the previous length forward, to add buffers
36
37
  // to what we already read.
@@ -141,6 +142,7 @@ export class DiskLoggerPage extends qreact.Component {
141
142
  if (file.endTime > lastTime) lastTime = file.endTime;
142
143
  let buffer = controller.getRemoteLogBuffer(file.nodeId, file.path);
143
144
  if (buffer) {
145
+ buffer = Zip.gunzipSync(buffer);
144
146
  buffers.push(buffer);
145
147
  } else {
146
148
  loadingCount++;
@@ -542,7 +544,14 @@ class DiskLoggerControllerBase {
542
544
  return await getLogFiles();
543
545
  }
544
546
  public async getLogBuffer(path: string): Promise<Buffer | undefined> {
545
- return await getLogBuffer(path);
547
+ // Always compress it. If it is in progress it can't be compressed on disk, but
548
+ // the compression ratio is so high it's worth it to compress it dynamically now,
549
+ // to speed up the network transfer.
550
+ let buffer = await getLogBuffer(path);
551
+ if (buffer && path.endsWith(".log")) {
552
+ buffer = await Zip.gzip(buffer);
553
+ }
554
+ return buffer;
546
555
  }
547
556
  }
548
557
 
@@ -552,14 +561,11 @@ export const DiskLoggerController = SocketFunction.register(
552
561
  () => ({
553
562
  getRemoteLogFiles: {},
554
563
  getRemoteLogBuffer: {
555
- compress: true,
556
564
  clientHooks: [cacheCalls]
557
565
  },
558
566
 
559
567
  getLogFiles: {},
560
- getLogBuffer: {
561
- compress: true,
562
- },
568
+ getLogBuffer: {},
563
569
  }),
564
570
  () => ({
565
571
  hooks: [assertIsManagementUser],
@@ -1,5 +1,5 @@
1
1
 
2
- import { batchFunction, runInfinitePoll } from "socket-function/src/batching";
2
+ import { batchFunction, runInfinitePoll, runInfinitePollCallAtStart } from "socket-function/src/batching";
3
3
  import { nextId, timeInDay, timeInHour } from "socket-function/src/misc";
4
4
  import { getStorageDir, getStorageFolder } from "../../fs";
5
5
  import fs from "fs";
@@ -8,6 +8,7 @@ import { SizeLimiter } from "../SizeLimiter";
8
8
  import { SocketFunction } from "socket-function/SocketFunction";
9
9
  import { isNode } from "typesafecss";
10
10
  import { logGitHashes } from "./logGitHashes";
11
+ import { Zip } from "../../zip";
11
12
 
12
13
  if (isNode()) {
13
14
  // Delayed setup, as we depend on diskLogger early, and we don't want to force high level
@@ -105,6 +106,7 @@ export type LogFile = {
105
106
  export async function getLogFiles(): Promise<LogFile[]> {
106
107
  let files = await fs.promises.readdir(folder);
107
108
  let paths = files.map(file => folder + file);
109
+ paths = paths.filter(x => x.endsWith(".log") || x.endsWith(".zip"));
108
110
  let objs = paths.map(decodeLogFileName);
109
111
  for (let obj of objs) {
110
112
  try {
@@ -214,7 +216,8 @@ function packageLogObj(args: unknown[]): LogObj {
214
216
 
215
217
  function decodeLogFileName(path: string): LogFile {
216
218
  let name = path.split("/").pop()!;
217
- let [start, end] = name.split(".log")[0].split("-").map(Number);
219
+ let withoutExt = name.split(".").slice(0, -1).join(".");
220
+ let [start, end] = withoutExt.split("-").map(Number);
218
221
  return {
219
222
  startTime: start,
220
223
  endTime: end,
@@ -231,7 +234,16 @@ const logBase = batchFunction({ delay: 0 }, async function logBase(logObjList: L
231
234
 
232
235
  let byLogPath = new Map<string, LogObj[]>();
233
236
  for (let log of logs) {
234
- let logFile = getLogFileName(log);
237
+ function createLogFileName(logObj: LogObj): LogFile {
238
+ let start = Math.floor(logObj.time / LOG_FILE_DURATION) * LOG_FILE_DURATION;
239
+ let startTime = start;
240
+ let endTime = start + LOG_FILE_DURATION;
241
+ let name = startTime + "-" + endTime + ".log";
242
+ let path = folder + name;
243
+ let logFile: LogFile = { startTime, endTime, name, path, size: 0, };
244
+ return logFile;
245
+ }
246
+ let logFile = createLogFileName(log);
235
247
  let list = byLogPath.get(logFile.path);
236
248
  if (!list) {
237
249
  list = [];
@@ -268,18 +280,9 @@ const logBase = batchFunction({ delay: 0 }, async function logBase(logObjList: L
268
280
  }
269
281
  });
270
282
 
271
- function getLogFileName(logObj: LogObj): LogFile {
272
- let start = Math.floor(logObj.time / LOG_FILE_DURATION) * LOG_FILE_DURATION;
273
- let startTime = start;
274
- let endTime = start + LOG_FILE_DURATION;
275
- let name = startTime + "-" + endTime + ".log";
276
- let path = folder + name;
277
- let logFile: LogFile = { startTime, endTime, name, path, size: 0, };
278
- return logFile;
279
- }
280
283
 
281
284
  if (isNode()) {
282
- runInfinitePoll(timeInHour, async function logClearOldLogs() {
285
+ runInfinitePoll(timeInHour, async function compressLogs() {
283
286
  // Maintain our size restrictions
284
287
  let logFiles = await fs.promises.readdir(folder);
285
288
  let objs: { time: number; bytes: number; path: string; }[] = [];
@@ -293,6 +296,23 @@ if (isNode()) {
293
296
  await fs.promises.unlink(file.path);
294
297
  }
295
298
  });
299
+ // Wait a random time, so we hopefully don't synchronize with any other services on this machine
300
+ void runInfinitePollCallAtStart(timeInHour + (1 + Math.random()), async function compressOldLogs() {
301
+ let logFiles = await fs.promises.readdir(folder);
302
+ let compressTime = Date.now() - LOG_FILE_DURATION * 2;
303
+ for (let file of logFiles) {
304
+ if (!file.endsWith(".log")) continue;
305
+ let path = folder + file;
306
+ if (decodeLogFileName(path).endTime > compressTime) continue;
307
+ let basePath = path.split(".").slice(0, -1).join(".");
308
+ let buffer = await fs.promises.readFile(path);
309
+ buffer = await Zip.gzip(buffer);
310
+ let tempPath = basePath + Math.random() + ".temp";
311
+ await fs.promises.writeFile(tempPath, buffer);
312
+ await fs.promises.rename(tempPath, basePath + ".zip");
313
+ await fs.promises.unlink(path);
314
+ }
315
+ });
296
316
  }
297
317
 
298
318
  /*
package/src/zip.ts CHANGED
@@ -61,6 +61,14 @@ export class Zip {
61
61
  }
62
62
  }
63
63
 
64
+ public static gunzipSync(buffer: Buffer): Buffer {
65
+ if (isNode()) {
66
+ return Buffer.from(zlib.gunzipSync(buffer));
67
+ } else {
68
+ return Buffer.from(pako.inflate(buffer));
69
+ }
70
+ }
71
+
64
72
  @measureFnc
65
73
  public static async gunzipBatch(buffers: Buffer[]): Promise<Buffer[]> {
66
74
  let time = Date.now();