mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 22:25:24 +00:00
fix: host imports running a defaults pass and metrics restart per host (#1384)
This commit is contained in:
1 parent
5e31642379
commit
11a22d30eb
6 files changed
+76
-10
No files matched your search
@@ -22,6 +22,8 @@ export interface MetricsViewersV1 {
|
||||
unregister: (hostId: number, viewerSessionId: string) => void;
|
||||
}
|
||||
|
||||
const RETIME_DEBOUNCE_MS = 1000;
|
||||
|
||||
export async function activate(ctx: PluginContext) {
|
||||
const log = createLogger(ctx.log);
|
||||
const repository = await createHostMetricsRepository(ctx.db);
|
||||
@@ -73,7 +75,19 @@ export async function activate(ctx: PluginContext) {
|
||||
const { hostId } = payload as { hostId?: number };
|
||||
if (hostId) poller.hostKeyAccepted(hostId);
|
||||
});
|
||||
ctx.settings.onChange("metricsInterval", () => void poller.retimeAll());
|
||||
// An import writes this once per host, and each write restarted every
|
||||
// polled host. One retime after the writes settle covers them all.
|
||||
let retime: ReturnType<typeof setTimeout> | null = null;
|
||||
ctx.settings.onChange("metricsInterval", () => {
|
||||
if (retime) clearTimeout(retime);
|
||||
retime = setTimeout(() => {
|
||||
retime = null;
|
||||
void poller.retimeAll();
|
||||
}, RETIME_DEBOUNCE_MS);
|
||||
});
|
||||
ctx.disposables.add(() => {
|
||||
if (retime) clearTimeout(retime);
|
||||
});
|
||||
|
||||
ctx.services.provide<MetricsViewersV1>("host-metrics.viewers", {
|
||||
register: async (hostId) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import express from "express";
|
||||
import {
|
||||
createMockCtx,
|
||||
@@ -9,6 +9,7 @@ import { PluginCapabilityError } from "@termix/plugin-sdk/backend";
|
||||
import { activate } from "../../src/backend/index.js";
|
||||
import type { MetricsViewersV1 } from "../../src/backend/index.js";
|
||||
import { hostImportNormalizer } from "../../src/backend/host-import.js";
|
||||
import { MetricsPoller } from "../../src/backend/poller.js";
|
||||
import { manifest, pluginDir, startServer, type TestServer } from "./server";
|
||||
|
||||
let db: TestDb | null = null;
|
||||
@@ -117,4 +118,23 @@ describe("hostImportNormalizer", () => {
|
||||
it("writes nothing for a row without metrics settings", () => {
|
||||
expect(hostImportNormalizer({ name: "x" })).toBeNull();
|
||||
});
|
||||
|
||||
it("retimes once after a burst of interval writes", async () => {
|
||||
server = await startServer();
|
||||
const retime = vi
|
||||
.spyOn(MetricsPoller.prototype, "retimeAll")
|
||||
.mockResolvedValue();
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
for (let hostId = 1; hostId <= 20; hostId++) {
|
||||
await server.mock.ctx.settings.setHost(hostId, "metricsInterval", 30);
|
||||
}
|
||||
expect(retime).not.toHaveBeenCalled();
|
||||
await vi.advanceTimersByTimeAsync(1500);
|
||||
expect(retime).toHaveBeenCalledTimes(1);
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
retime.mockRestore();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user