mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-23 03:27:43 +09:00
Keep service metrics stable across metadata refreshes [skip version]
This commit is contained in:
1 parent
116f817197
commit
1ace946ab9
4 files changed
+21
-7
No files matched your search
@@ -40,6 +40,8 @@ Changes after 1.9.28 on the development branch.
|
||||
lines as readable structured entries (PR #136).
|
||||
- Keep remote application log requests on their assigned server instead of
|
||||
looking up the recorded container on the panel host.
|
||||
- Avoid restarting service metrics requests when unrelated application metadata
|
||||
refreshes.
|
||||
- Close the container inspector when opening Logs or Exec so it can no longer
|
||||
cover those surfaces (PR #137).
|
||||
|
||||
|
||||
@@ -155,6 +155,12 @@ try {
|
||||
window.serviceFixture.setApp({ id: 1, name: 'alpha', app_type: 'docker' });
|
||||
});
|
||||
await page.waitForFunction(() => window.serviceFixture.state.pending.length === 1);
|
||||
await action(() => window.serviceFixture.setApp({
|
||||
id: 1, name: 'alpha', app_type: 'docker', status: 'running',
|
||||
}));
|
||||
await page.waitForTimeout(50);
|
||||
assert.equal(await action(() => window.serviceFixture.state.pending.length), 1,
|
||||
'recreated app metadata does not restart an in-flight metrics request');
|
||||
await action(() => window.serviceFixture.state.pending.shift().resolve({ cpu_percent: 42 }));
|
||||
await page.locator('#service .metrics-tab').waitFor();
|
||||
assert.match(await page.locator('#service').innerText(), /42\.0%/);
|
||||
@@ -197,7 +203,7 @@ try {
|
||||
await action(() => window.serviceFixture.state.python.shift()({ active: false }));
|
||||
await page.locator('#service .metrics-tab').waitFor();
|
||||
assert.deepEqual(errors, []);
|
||||
console.log('Service metrics regression passed: missing container, failed poll, app switch, late response and Python state reset.');
|
||||
console.log('Service metrics regression passed: stable metadata refresh, missing container, failed poll, app switch, late response and Python state reset.');
|
||||
console.log('Metrics browser regression passed: slow response, manual sharing, socket loss/reconnect, hidden tab, remote selection, refresh off; widget sharing, refresh retention, workspace isolation.');
|
||||
} finally {
|
||||
await browser?.close();
|
||||
|
||||
@@ -19,6 +19,7 @@ const MetricsTabContent = ({ app }) => {
|
||||
|
||||
const isDocker = app.app_type === 'docker';
|
||||
const isPython = ['flask', 'django'].includes(app.app_type);
|
||||
const { id: appId, name: appName, container_id: containerId } = app;
|
||||
|
||||
// Load on mount and whenever the app changes; poll on top of that.
|
||||
const loadMetrics = useCallback(async () => {
|
||||
@@ -26,7 +27,9 @@ const MetricsTabContent = ({ app }) => {
|
||||
try {
|
||||
if (isDocker) {
|
||||
const data = await api.getContainers(true);
|
||||
const runtimeId = resolveAppContainerId(app, data.containers || []);
|
||||
const runtimeId = resolveAppContainerId(
|
||||
{ id: appId, name: appName, container_id: containerId }, data.containers || []
|
||||
);
|
||||
if (runtimeId) {
|
||||
const containerStats = normalizeContainerStats(
|
||||
await api.getContainerStats(runtimeId)
|
||||
@@ -36,7 +39,7 @@ const MetricsTabContent = ({ app }) => {
|
||||
setStats(null);
|
||||
}
|
||||
} else if (isPython) {
|
||||
const data = await api.getPythonAppStatus(app.id);
|
||||
const data = await api.getPythonAppStatus(appId);
|
||||
if (currentRequest === requestId.current) setProcessInfo(data);
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -47,7 +50,7 @@ const MetricsTabContent = ({ app }) => {
|
||||
} finally {
|
||||
if (currentRequest === requestId.current) setLoading(false);
|
||||
}
|
||||
}, [app, isDocker, isPython]);
|
||||
}, [appId, appName, containerId, isDocker, isPython]);
|
||||
|
||||
useEffect(() => {
|
||||
loadMetrics();
|
||||
|
||||
@@ -35,13 +35,16 @@ const OverviewTab = ({ app, deployConfig }) => {
|
||||
|
||||
const isDocker = app.app_type === 'docker';
|
||||
const isPython = ['flask', 'django'].includes(app.app_type);
|
||||
const { id: appId, name: appName, container_id: containerId } = app;
|
||||
|
||||
// Load on mount and whenever the app changes; poll on top of that.
|
||||
const loadMetrics = useCallback(async () => {
|
||||
try {
|
||||
if (isDocker) {
|
||||
const data = await api.getContainers(true);
|
||||
const runtimeId = resolveAppContainerId(app, data.containers || []);
|
||||
const runtimeId = resolveAppContainerId(
|
||||
{ id: appId, name: appName, container_id: containerId }, data.containers || []
|
||||
);
|
||||
if (runtimeId) {
|
||||
const containerStats = normalizeContainerStats(
|
||||
await api.getContainerStats(runtimeId)
|
||||
@@ -55,7 +58,7 @@ const OverviewTab = ({ app, deployConfig }) => {
|
||||
});
|
||||
}
|
||||
} else if (isPython) {
|
||||
const data = await api.getPythonAppStatus(app.id);
|
||||
const data = await api.getPythonAppStatus(appId);
|
||||
setMetrics({
|
||||
active: data.active,
|
||||
pid: data.pid,
|
||||
@@ -69,7 +72,7 @@ const OverviewTab = ({ app, deployConfig }) => {
|
||||
} finally {
|
||||
setMetricsLoading(false);
|
||||
}
|
||||
}, [app, isDocker, isPython]);
|
||||
}, [appId, appName, containerId, isDocker, isPython]);
|
||||
|
||||
useEffect(() => { loadMetrics(); }, [loadMetrics]);
|
||||
usePolling(loadMetrics, METRICS_REFRESH_MS, { immediate: false });
|
||||
|
||||
Reference in new issue
Block a user