mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 15:09:10 +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 'dotenv/config';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
@@ -200,7 +200,7 @@ export const startServer = async (
|
|||||||
clock: state.clock,
|
clock: state.clock,
|
||||||
timer: state.timer,
|
timer: state.timer,
|
||||||
onAir: state.timer.playback !== Playback.Stop,
|
onAir: state.timer.playback !== Playback.Stop,
|
||||||
message: messageService.getState(),
|
message: { ...runtimeStorePlaceholder.message },
|
||||||
runtime: state.runtime,
|
runtime: state.runtime,
|
||||||
eventNow: state.eventNow,
|
eventNow: state.eventNow,
|
||||||
currentBlock: {
|
currentBlock: {
|
||||||
@@ -224,6 +224,9 @@ export const startServer = async (
|
|||||||
const persistedCustomFields = getDataProvider().getCustomFields();
|
const persistedCustomFields = getDataProvider().getCustomFields();
|
||||||
initRundown(persistedRundown, persistedCustomFields);
|
initRundown(persistedRundown, persistedCustomFields);
|
||||||
|
|
||||||
|
// initialise message service
|
||||||
|
messageService.init(eventStore.set, eventStore.get);
|
||||||
|
|
||||||
// load restore point if it exists
|
// load restore point if it exists
|
||||||
const maybeRestorePoint = await restoreService.load();
|
const maybeRestorePoint = await restoreService.load();
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,21 @@ import { MessageState, runtimeStorePlaceholder } from 'ontime-types';
|
|||||||
import { DeepPartial } from 'ts-essentials';
|
import { DeepPartial } from 'ts-essentials';
|
||||||
|
|
||||||
import { throttle } from '../../utils/throttle.js';
|
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
|
* 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
|
* Exposes function to reset the internal state
|
||||||
@@ -22,7 +31,7 @@ export function clear() {
|
|||||||
* Exposes the internal state of the message service
|
* Exposes the internal state of the message service
|
||||||
*/
|
*/
|
||||||
export function getState(): MessageState {
|
export function getState(): MessageState {
|
||||||
return eventStore.get('message');
|
return storeGet('message');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,31 +2,32 @@ import * as messageService from '../MessageService.js';
|
|||||||
|
|
||||||
describe('MessageService', () => {
|
describe('MessageService', () => {
|
||||||
beforeEach(() => {
|
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();
|
messageService.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should patch the message state', () => {
|
it('should patch the message state', () => {
|
||||||
const message = {
|
const newState = messageService.patch({
|
||||||
timer: { text: 'new text', visible: true },
|
timer: { text: 'new text', visible: true },
|
||||||
external: 'external',
|
external: 'external',
|
||||||
};
|
});
|
||||||
|
|
||||||
const newState = messageService.patch(message);
|
expect(newState).toMatchObject({
|
||||||
|
|
||||||
expect(newState).toEqual({
|
|
||||||
timer: { text: 'new text', visible: true, blackout: false, blink: false, secondarySource: null },
|
timer: { text: 'new text', visible: true, blackout: false, blink: false, secondarySource: null },
|
||||||
external: 'external',
|
external: 'external',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not affect other properties when patching', () => {
|
it('should not affect other properties when patching', () => {
|
||||||
const initialMessage = {
|
const newState = messageService.patch({
|
||||||
timer: { text: 'initial text', visible: true },
|
timer: { text: 'initial text', visible: true },
|
||||||
};
|
});
|
||||||
|
|
||||||
const newState = messageService.patch(initialMessage);
|
expect(newState).toMatchObject({
|
||||||
|
|
||||||
expect(newState).toEqual({
|
|
||||||
timer: { text: 'initial text', visible: true, blackout: false, blink: false, secondarySource: null },
|
timer: { text: 'initial text', visible: true, blackout: false, blink: false, secondarySource: null },
|
||||||
external: '',
|
external: '',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { RuntimeStore } from 'ontime-types';
|
|||||||
import { socket } from '../adapters/WebsocketAdapter.js';
|
import { socket } from '../adapters/WebsocketAdapter.js';
|
||||||
|
|
||||||
export type PublishFn = <T extends keyof RuntimeStore>(key: T, value: RuntimeStore[T]) => void;
|
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> = {};
|
let store: Partial<RuntimeStore> = {};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user