Fixes reactivity.

This commit is contained in:
2023-09-26 14:00:43 +02:00
parent f1b46b788d
commit ca1badad00
7 changed files with 31 additions and 61 deletions

View File

@@ -1,6 +1,5 @@
import { dev } from '$app/environment'; import { dev } from '$app/environment';
import { initConfig, watchDymamicConfig } from '$lib/server/config'; import { initConfig, watchDymamicConfig } from '$lib/server/config';
import { initServicePolling } from '$lib/server/serviceDataPolling';
import { initComponents, initServices } from '$lib/services/services'; import { initComponents, initServices } from '$lib/services/services';
if (!dev) { if (!dev) {
@@ -12,4 +11,3 @@ if (!dev) {
await initServices(); await initServices();
await initComponents(); await initComponents();
initConfig(); initConfig();
initServicePolling();

View File

@@ -10,7 +10,7 @@
const component = getServiceComponent(service.type || ''); const component = getServiceComponent(service.type || '');
function computeClasses(): string { function computeClasses(status: ServiceStatus | undefined): string {
switch (status) { switch (status) {
case 'offline': case 'offline':
return 'bg-error-400'; return 'bg-error-400';
@@ -20,7 +20,7 @@
return 'bg-warning-400 animate-pulse'; return 'bg-warning-400 animate-pulse';
} }
} }
$: statusClasses = computeClasses(); $: statusClasses = computeClasses(status);
</script> </script>
<a <a

View File

@@ -11,9 +11,9 @@ import type {
} from '$lib/config'; } from '$lib/config';
import * as ipRangeCheck from 'ip-range-check'; import * as ipRangeCheck from 'ip-range-check';
import { initializeServiceData } from './serviceDataPolling';
import { getServiceRecord } from '$lib/services/services'; import { getServiceRecord } from '$lib/services/services';
import { rootLogger } from './logger'; import { rootLogger } from './logger';
import { resetServiceData } from './dataPolling';
const requiredService: Required<ServiceConfig> = { const requiredService: Required<ServiceConfig> = {
title: '', title: '',
@@ -191,7 +191,7 @@ let _clientConfig: Config = defaultConfig;
function buildServerAndClientConfig(config: SPOJO) { function buildServerAndClientConfig(config: SPOJO) {
_serverConfig = mergeConfig(defaultConfig, config); _serverConfig = mergeConfig(defaultConfig, config);
_clientConfig = stripPrivateFields(_serverConfig); _clientConfig = stripPrivateFields(_serverConfig);
initializeServiceData(); resetServiceData();
} }
export function initConfig() { export function initConfig() {

View File

@@ -8,15 +8,6 @@ export type MayAsyncServiceData = Partial<ServiceData> | Promise<Partial<Service
const logger = rootLogger.child({ name: 'ServiceData' }); const logger = rootLogger.child({ name: 'ServiceData' });
export function getCurrentServiceData(): Array<Array<MayAsyncServiceData>> {
logger.trace('getCurrentServiceData()');
if (serviceData.length != 0) {
return serviceData;
}
logger.debug('polling for initial state');
return pollAllServices();
}
export interface ServiceDataEvent { export interface ServiceDataEvent {
group: number; group: number;
item: number; item: number;
@@ -28,21 +19,33 @@ export const serviceDataEvents = readable<ServiceDataEvent>(undefined, (set) =>
pushServiceData = set; pushServiceData = set;
if (serviceData.length == 0) {
logger.debug('polling for initial state');
pollAllServices();
}
const timer = setInterval(() => { const timer = setInterval(() => {
logger.debug('polling for service update'); logger.debug('polling for service update');
pollAllServices(); pollAllServices();
}, pollInterval); }, pollInterval);
return () => { return () => {
logger.debug('stopping polling loop and clearing data'); logger.debug('stopping polling loop and clearing data');
clearInterval(timer); clearInterval(timer);
serviceData = []; serviceData = [];
pushServiceData = () => {}; pushServiceData = undefined;
}; };
}); });
let pushServiceData: (value: ServiceDataEvent) => void = () => {}; export function resetServiceData() {
serviceData = [];
if (pushServiceData != undefined) {
pollAllServices();
}
}
const pollInterval = 5000; let pushServiceData: ((value: ServiceDataEvent) => void) | undefined = undefined;
const pollInterval = 30000;
let serviceData: Array<Array<MayAsyncServiceData>> = []; let serviceData: Array<Array<MayAsyncServiceData>> = [];
@@ -62,7 +65,9 @@ function pollAllServices(): Array<Array<MayAsyncServiceData>> {
.then((data: ServiceData) => { .then((data: ServiceData) => {
serviceLogger.trace({ data }, 'pollAllService:result()'); serviceLogger.trace({ data }, 'pollAllService:result()');
serviceData[idxGroup][idxItem] = data; serviceData[idxGroup][idxItem] = data;
pushServiceData({ group: idxGroup, item: idxItem, data }); if (pushServiceData != undefined) {
pushServiceData({ group: idxGroup, item: idxItem, data });
}
return data; return data;
}) })
.catch((error) => { .catch((error) => {

View File

@@ -1,36 +0,0 @@
import type { Config } from '$lib/config';
import type { ServiceData, ServicePoller } from '$lib/services/service';
import { getServiceRecord } from '$lib/services/services';
import { serverConfig } from './config';
export const serviceData: Array<Array<Partial<ServiceData> | Promise<Partial<ServiceData>>>> = [];
function pollServices() {
const config: Config = serverConfig();
for (const [i, group] of config.services.entries()) {
for (const [j, service] of group.items.entries()) {
const poller: ServicePoller = getServiceRecord(service.type || '').poll;
serviceData[i][j] = poller(service).then((data: ServiceData) => {
serviceData[i][j] = data;
return data;
});
}
}
}
export function initializeServiceData() {
const config = serverConfig();
serviceData.length = config.services.length;
for (let i = 0; i < serviceData.length; i++) {
serviceData[i] = [];
for (let j = 0; j < config.services[i].items.length; j++) {
serviceData[i][j] = {};
}
}
}
export function initServicePolling() {
pollServices();
setInterval(pollServices, 30000);
}

View File

@@ -1,8 +1,5 @@
import { clientAddressIsPrivate, clientConfig, serverConfig } from '$lib/server/config'; import { clientAddressIsPrivate, clientConfig, serverConfig } from '$lib/server/config';
import type { PageServerLoad } from './$types.d'; import type { PageServerLoad } from './$types.d';
import { serviceData } from '$lib/server/serviceDataPolling';
import { getCurrentServiceData } from '$lib/server/dataPolling';
import { request } from '@playwright/test';
import { requestLogger } from '$lib/server/logger'; import { requestLogger } from '$lib/server/logger';
export const load: PageServerLoad = async ({ getClientAddress }) => { export const load: PageServerLoad = async ({ getClientAddress }) => {
@@ -12,7 +9,6 @@ export const load: PageServerLoad = async ({ getClientAddress }) => {
return { return {
config: clientConfig(), config: clientConfig(),
serviceData: getCurrentServiceData(),
location: getClientAddress(), location: getClientAddress(),
privateAccess: clientAddressIsPrivate(getClientAddress(), serverConfig()) privateAccess: clientAddressIsPrivate(getClientAddress(), serverConfig())
}; };

View File

@@ -5,17 +5,24 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
import type { ServiceDataEvent } from '$lib/server/dataPolling'; import type { ServiceDataEvent } from '$lib/server/dataPolling';
import type { ServiceData } from '$lib/services/service';
export let data: PageData; export let data: PageData;
const serviceData: Array<Array<Partial<ServiceData>>> = [];
for (const [i, group] of data.config.services.entries()) {
serviceData[i] = new Array(group.items.length).fill({});
}
onMount(() => { onMount(() => {
const sse = new EventSource('/api/updates'); const sse = new EventSource('/api/updates');
sse.onmessage = (e) => { sse.onmessage = (e) => {
if (e.data == undefined || e.data === 'undefined') { if (e.data == undefined || e.data === 'undefined') {
return; return;
} }
const event = JSON.parse(e.data) as ServiceDataEvent; const event = JSON.parse(e.data) as ServiceDataEvent;
data.serviceData[event.group][event.item] = event.data; serviceData[event.group][event.item] = event.data;
console.log(event.data);
}; };
return () => { return () => {
@@ -56,7 +63,7 @@
<main class="mb-auto mt-16 gap-12 {layoutClasses}"> <main class="mb-auto mt-16 gap-12 {layoutClasses}">
{#each data.config.services as group, i} {#each data.config.services as group, i}
<ServiceGroup {group} groupData={data.serviceData[i]} {columns} /> <ServiceGroup {group} groupData={serviceData[i]} {columns} />
{/each} {/each}
</main> </main>