Skip to content

Commit

Permalink
refactor: improve integration updates
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed May 11, 2024
1 parent 61da610 commit 54f4693
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 40 deletions.
38 changes: 21 additions & 17 deletions apps/server/src/services/runtime-service/RuntimeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ import {
getPlayableEvents,
} from '../rundown-service/rundownUtils.js';
import { integrationService } from '../integration-service/IntegrationService.js';
import { getShouldClockUpdate, getShouldTimerUpdate } from './rundownService.utils.js';
import { getForceUpdate, getShouldClockUpdate, getShouldTimerUpdate } from './rundownService.utils.js';

/**
* Service manages runtime status of app
* Coordinating with necessary services
*/
class RuntimeService {
private eventTimer: TimerService | null = null;
private lastOnUpdate = -1;
private lastIntegrationClockUpdate = -1;
private lastIntegrationTimerValue = -1;

/** last time we updated the socket */
static previousTimerUpdate: number;
Expand Down Expand Up @@ -66,19 +67,25 @@ class RuntimeService {
}
}

// update normal cycle
if (newState.clock - this.lastOnUpdate >= timerConfig.notificationRate) {
const hasRunningTimer = Boolean(newState.eventNow) && newState.timer.playback === Playback.Play;
if (hasRunningTimer) {
process.nextTick(() => {
integrationService.dispatch(TimerLifeCycle.onUpdate);
});
}
const hasRunningTimer = Boolean(newState.eventNow) && newState.timer.playback === Playback.Play;
const shouldUpdateTimer =
hasRunningTimer && getShouldTimerUpdate(this.lastIntegrationTimerValue, newState.timer.current);

if (shouldUpdateTimer) {
process.nextTick(() => {
integrationService.dispatch(TimerLifeCycle.onUpdate);
});

this.lastIntegrationTimerValue = newState.timer.current;
}

const shouldUpdateClock = getShouldClockUpdate(this.lastIntegrationClockUpdate, newState.clock);
if (shouldUpdateClock) {
process.nextTick(() => {
integrationService.dispatch(TimerLifeCycle.onClock);
});

this.lastOnUpdate = newState.clock;
this.lastIntegrationClockUpdate = newState.clock;
}

if (shouldCallRoll) {
Expand Down Expand Up @@ -522,12 +529,9 @@ function broadcastResult(_target: any, _propertyKey: string, descriptor: Propert
// to apply custom logic for different datasets

const shouldUpdateClock = getShouldClockUpdate(RuntimeService.previousClockUpdate, state.clock);
const shouldUpdateTimer = getShouldTimerUpdate(
RuntimeService.previousTimerValue,
state.timer.current,
RuntimeService.previousTimerUpdate,
state.clock,
);
const shouldForceTimerUpdate = getForceUpdate(RuntimeService.previousTimerUpdate, state.clock);
const shouldUpdateTimer =
shouldForceTimerUpdate || getShouldTimerUpdate(RuntimeService.previousTimerValue, state.timer.current);

// some changes need an immediate update
const hasNewLoaded = state.eventNow?.id !== RuntimeService.previousState?.eventNow?.id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,21 @@ describe('getShouldTimerUpdate', () => {
it('should return false when currentValue is null', () => {
const previousValue = 0;
const currentValue = null;
const previousUpdate = 0;
const now = 0;
const result = getShouldTimerUpdate(previousValue, currentValue, previousUpdate, now);
const result = getShouldTimerUpdate(previousValue, currentValue);
expect(result).toBe(false);
});

it('should return true when timer is a second ahead', () => {
const previousValue = 5000;
const currentValue = 6500;
const previousUpdate = Date.now();
const now = Date.now();
const result = getShouldTimerUpdate(previousValue, currentValue, previousUpdate, now);
const result = getShouldTimerUpdate(previousValue, currentValue);
expect(result).toBe(true);
});

it('should return false when timer is not a second ahead and force update is not required', () => {
const previousValue = 5000;
const currentValue = 5500;
const previousUpdate = Date.now();
const now = Date.now();
const result = getShouldTimerUpdate(previousValue, currentValue, previousUpdate, now);
const result = getShouldTimerUpdate(previousValue, currentValue);
expect(result).toBe(false);
});
});
16 changes: 2 additions & 14 deletions apps/server/src/services/runtime-service/rundownService.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,14 @@ export function getShouldClockUpdate(previousUpdate: number, now: number): boole

/**
* Checks whether we should update the timer value
* - timer has slid (?)
* - we have rolled into a new seconds unit
*/
export function getShouldTimerUpdate(
previousValue: number,
currentValue: MaybeNumber,
previousUpdate: number,
now: number,
): boolean {
export function getShouldTimerUpdate(previousValue: number, currentValue: MaybeNumber): boolean {
if (currentValue === null) {
return false;
}

const shouldForceUpdate = getForceUpdate(previousUpdate, now);
if (shouldForceUpdate) {
return true;
}

const shouldUpdateTimer = millisToSeconds(currentValue) !== millisToSeconds(previousValue + timerConfig.triggerAhead);

return shouldUpdateTimer;
}

Expand All @@ -47,7 +35,7 @@ export function getShouldTimerUpdate(
* - if the clock has slid back
* - if we have escaped the update rate (clock slid forward)
*/
function getForceUpdate(previousUpdate: number, now: number): boolean {
export function getForceUpdate(previousUpdate: number, now: number): boolean {
const isClockBehind = now < previousUpdate;
const hasExceededRate = now - previousUpdate >= timerConfig.notificationRate;
return isClockBehind || hasExceededRate;
Expand Down

0 comments on commit 54f4693

Please sign in to comment.