mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-07 08:23:55 +00:00
refactor: prevent race conditions on init
This commit is contained in:
committed by
Carlos Valente
parent
f65ec0da3c
commit
0dfef732bf
@@ -1,4 +1,4 @@
|
||||
import { LogOrigin, Playback, SimpleDirection, SimplePlayback } from 'ontime-types';
|
||||
import { LogOrigin, Playback, runtimeStorePlaceholder, SimpleDirection, SimplePlayback } from 'ontime-types';
|
||||
|
||||
import 'dotenv/config';
|
||||
import express from 'express';
|
||||
@@ -200,7 +200,7 @@ export const startServer = async (
|
||||
clock: state.clock,
|
||||
timer: state.timer,
|
||||
onAir: state.timer.playback !== Playback.Stop,
|
||||
message: messageService.getState(),
|
||||
message: { ...runtimeStorePlaceholder.message },
|
||||
runtime: state.runtime,
|
||||
eventNow: state.eventNow,
|
||||
currentBlock: {
|
||||
@@ -224,6 +224,9 @@ export const startServer = async (
|
||||
const persistedCustomFields = getDataProvider().getCustomFields();
|
||||
initRundown(persistedRundown, persistedCustomFields);
|
||||
|
||||
// initialise message service
|
||||
messageService.init(eventStore.set, eventStore.get);
|
||||
|
||||
// load restore point if it exists
|
||||
const maybeRestorePoint = await restoreService.load();
|
||||
|
||||
|
||||
@@ -2,12 +2,21 @@ import { MessageState, runtimeStorePlaceholder } from 'ontime-types';
|
||||
import { DeepPartial } from 'ts-essentials';
|
||||
|
||||
import { throttle } from '../../utils/throttle.js';
|
||||
import { eventStore, type PublishFn } from '../../stores/EventStore.js';
|
||||
import type { StoreGetter, PublishFn } from '../../stores/EventStore.js';
|
||||
|
||||
/**
|
||||
* Create a throttled version of the set function
|
||||
*/
|
||||
const throttledSet: PublishFn = throttle(eventStore.set, 100);
|
||||
let throttledSet: PublishFn = () => undefined;
|
||||
let storeGet: StoreGetter = (_key: string) => undefined;
|
||||
|
||||
/**
|
||||
* Allows providing store interfaces
|
||||
*/
|
||||
export function init(storeSetter: PublishFn, storeGetter: StoreGetter) {
|
||||
throttledSet = throttle(storeSetter, 100);
|
||||
storeGet = storeGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes function to reset the internal state
|
||||
@@ -22,7 +31,7 @@ export function clear() {
|
||||
* Exposes the internal state of the message service
|
||||
*/
|
||||
export function getState(): MessageState {
|
||||
return eventStore.get('message');
|
||||
return storeGet('message');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,31 +2,32 @@ import * as messageService from '../MessageService.js';
|
||||
|
||||
describe('MessageService', () => {
|
||||
beforeEach(() => {
|
||||
// at runtime, the store is instantiated before the message service
|
||||
const store = {};
|
||||
const storeSetter = (key, value) => (store[key] = value);
|
||||
const storeGetter = (key) => store[key];
|
||||
messageService.init(storeSetter, storeGetter);
|
||||
messageService.clear();
|
||||
});
|
||||
|
||||
it('should patch the message state', () => {
|
||||
const message = {
|
||||
const newState = messageService.patch({
|
||||
timer: { text: 'new text', visible: true },
|
||||
external: 'external',
|
||||
};
|
||||
});
|
||||
|
||||
const newState = messageService.patch(message);
|
||||
|
||||
expect(newState).toEqual({
|
||||
expect(newState).toMatchObject({
|
||||
timer: { text: 'new text', visible: true, blackout: false, blink: false, secondarySource: null },
|
||||
external: 'external',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not affect other properties when patching', () => {
|
||||
const initialMessage = {
|
||||
const newState = messageService.patch({
|
||||
timer: { text: 'initial text', visible: true },
|
||||
};
|
||||
});
|
||||
|
||||
const newState = messageService.patch(initialMessage);
|
||||
|
||||
expect(newState).toEqual({
|
||||
expect(newState).toMatchObject({
|
||||
timer: { text: 'initial text', visible: true, blackout: false, blink: false, secondarySource: null },
|
||||
external: '',
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import { RuntimeStore } from 'ontime-types';
|
||||
import { socket } from '../adapters/WebsocketAdapter.js';
|
||||
|
||||
export type PublishFn = <T extends keyof RuntimeStore>(key: T, value: RuntimeStore[T]) => void;
|
||||
export type StoreGetter = <T extends keyof RuntimeStore>(key: T) => Partial<RuntimeStore>[T];
|
||||
|
||||
let store: Partial<RuntimeStore> = {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user