Fixes multiple client connection data freshness.

This commit is contained in:
2023-09-26 14:20:35 +02:00
parent ca1badad00
commit cfbe7594e8
2 changed files with 20 additions and 15 deletions

View File

@@ -3,8 +3,7 @@ import { getServiceRecord } from '$lib/services/services';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
import { serverConfig } from './config'; import { serverConfig } from './config';
import { rootLogger } from './logger'; import { rootLogger } from './logger';
import type { Unsubscriber } from 'svelte/motion';
export type MayAsyncServiceData = Partial<ServiceData> | Promise<Partial<ServiceData>>;
const logger = rootLogger.child({ name: 'ServiceData' }); const logger = rootLogger.child({ name: 'ServiceData' });
@@ -14,15 +13,22 @@ export interface ServiceDataEvent {
data: ServiceData; data: ServiceData;
} }
export const serviceDataEvents = readable<ServiceDataEvent>(undefined, (set) => { export function subscribeToDataEvent(onEvent: (event: ServiceDataEvent) => void): Unsubscriber {
for (const [group, items] of serviceData.entries()) {
for (const [item, data] of items.entries()) {
onEvent({ group, item, data: data as ServiceData });
}
}
return serviceDataEvents.subscribe(onEvent);
}
const serviceDataEvents = readable<ServiceDataEvent>(undefined, (set) => {
logger.debug({ interval: pollInterval }, 'starting polling loop'); logger.debug({ interval: pollInterval }, 'starting polling loop');
pushServiceData = set; pushServiceData = set;
if (serviceData.length == 0) { logger.debug('polling for initial state');
logger.debug('polling for initial state'); pollAllServices();
pollAllServices();
}
const timer = setInterval(() => { const timer = setInterval(() => {
logger.debug('polling for service update'); logger.debug('polling for service update');
pollAllServices(); pollAllServices();
@@ -47,9 +53,9 @@ let pushServiceData: ((value: ServiceDataEvent) => void) | undefined = undefined
const pollInterval = 30000; const pollInterval = 30000;
let serviceData: Array<Array<MayAsyncServiceData>> = []; let serviceData: Array<Array<Partial<ServiceData>>> = [];
function pollAllServices(): Array<Array<MayAsyncServiceData>> { function pollAllServices() {
logger.trace('pollAllServices()'); logger.trace('pollAllServices()');
const config = serverConfig(); const config = serverConfig();
@@ -61,7 +67,8 @@ function pollAllServices(): Array<Array<MayAsyncServiceData>> {
for (const [idxItem, service] of group.items.entries()) { for (const [idxItem, service] of group.items.entries()) {
const poller: ServicePoller = getServiceRecord(service.type || '').poll; const poller: ServicePoller = getServiceRecord(service.type || '').poll;
const serviceLogger = logger.child({ group: idxGroup, item: idxItem, service }); const serviceLogger = logger.child({ group: idxGroup, item: idxItem, service });
serviceData[idxGroup][idxItem] = poller(service) serviceData[idxGroup][idxItem] = {};
poller(service)
.then((data: ServiceData) => { .then((data: ServiceData) => {
serviceLogger.trace({ data }, 'pollAllService:result()'); serviceLogger.trace({ data }, 'pollAllService:result()');
serviceData[idxGroup][idxItem] = data; serviceData[idxGroup][idxItem] = data;
@@ -76,6 +83,4 @@ function pollAllServices(): Array<Array<MayAsyncServiceData>> {
}); });
} }
} }
return serviceData;
} }

View File

@@ -1,5 +1,5 @@
import { serviceDataEvents } from '$lib/server/dataPolling'; import { subscribeToDataEvent } from '$lib/server/dataPolling';
import { requestLogger, rootLogger } from '$lib/server/logger'; import { requestLogger } from '$lib/server/logger';
import type { RequestHandler } from '@sveltejs/kit'; import type { RequestHandler } from '@sveltejs/kit';
import type { Unsubscriber } from 'svelte/store'; import type { Unsubscriber } from 'svelte/store';
@@ -17,7 +17,7 @@ export const GET: RequestHandler = ({ getClientAddress }) => {
start: (controller) => { start: (controller) => {
logger.info('new update request stream started'); logger.info('new update request stream started');
unsubscribe = serviceDataEvents.subscribe((event) => { unsubscribe = subscribeToDataEvent((event) => {
logger.trace({ event: event }, 'sending new event'); logger.trace({ event: event }, 'sending new event');
const data = `event:message\ndata:${JSON.stringify(event)}\n\n`; const data = `event:message\ndata:${JSON.stringify(event)}\n\n`;
controller.enqueue(data); controller.enqueue(data);