Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-Arc committed Jan 24, 2025
1 parent 85b27e6 commit 023b462
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 69 deletions.
8 changes: 1 addition & 7 deletions apps/client/src/common/utils/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export const connectSocket = () => {
}

socketSendJson('set-client-type', 'ontime');
socketSendJson('set-client-use-patch', 'ontime');
setOnlineStatus(true);
};

Expand All @@ -65,6 +64,7 @@ export const connectSocket = () => {
websocket.onmessage = (event) => {
try {
const data = JSON.parse(event.data);

const { type, payload } = data;

if (!type) {
Expand Down Expand Up @@ -139,12 +139,6 @@ export const connectSocket = () => {
updateDevTools(serverPayload);
break;
}
case 'ontime-patch': {
patchRuntime(payload);
updateDevTools(payload);
break;
}
//TODO: remove all other types as they are now patched
case 'ontime-clock': {
patchRuntimeProperty('clock', payload);
updateDevTools({ clock: payload });
Expand Down
56 changes: 1 addition & 55 deletions apps/server/src/adapters/WebsocketAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* Payload: adds necessary payload for the request to be completed
*/

import { Client, LogOrigin, RuntimeStore } from 'ontime-types';
import { Client, LogOrigin } from 'ontime-types';

import { WebSocket, WebSocketServer } from 'ws';
import type { Server } from 'http';
Expand All @@ -37,9 +37,6 @@ export class SocketServer implements IAdapter {
private lastConnection: Date | null = null;
private shouldShowWelcome = true;

private readonly patchClients: Map<string, WebSocket>;
private readonly keyClients: Map<string, WebSocket>;

constructor() {
if (instance) {
throw new Error('There can be only one');
Expand All @@ -48,8 +45,6 @@ export class SocketServer implements IAdapter {
// eslint-disable-next-line @typescript-eslint/no-this-alias -- this logic is used to ensure singleton
instance = this;
this.clients = new Map<string, Client>();
this.keyClients = new Map<string, WebSocket>();
this.patchClients = new Map<string, WebSocket>();
this.wss = null;
}

Expand All @@ -72,8 +67,6 @@ export class SocketServer implements IAdapter {
path: '',
});

this.keyClients.set(clientId, ws);

this.lastConnection = new Date();
logger.info(LogOrigin.Client, `${this.clients.size} Connections with new: ${clientId}`);

Expand Down Expand Up @@ -105,9 +98,6 @@ export class SocketServer implements IAdapter {

ws.on('close', () => {
this.clients.delete(clientId);
this.patchClients.delete(clientId);
this.keyClients.delete(clientId);

logger.info(LogOrigin.Client, `${this.clients.size} Connections with disconnected: ${clientId}`);
this.sendClientList();
});
Expand Down Expand Up @@ -191,18 +181,6 @@ export class SocketServer implements IAdapter {
return;
}

if (type === 'set-client-use-patch') {
this.keyClients.delete(clientId);
this.patchClients.set(clientId, ws);
return;
}

if (type === 'set-client-use-key') {
this.patchClients.delete(clientId);
this.keyClients.set(clientId, ws);
return;
}

// Protocol specific stuff handled above
try {
const reply = dispatchFromAdapter(type, payload, 'ws');
Expand Down Expand Up @@ -285,38 +263,6 @@ export class SocketServer implements IAdapter {
}
}

public sendRuntimeStoreUpdate(keysToUpdate: (keyof RuntimeStore)[], store: Partial<RuntimeStore>) {
// create a patch object with all the keys marked for updating
const patch = {};
keysToUpdate.map((key) => {
Object.assign(patch, { [key]: store[key] });
});

//convert to JSON once and reuse
const stringifiedPatch = JSON.stringify({ type: 'ontime-patch', payload: patch });

// for each client that have subscribed to the patch method send the patch object
this.patchClients.forEach((ws) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(stringifiedPatch);
}
});

// all the old type clients are sent the normal way
while (keysToUpdate.length) {
// for each key in the list
const key = keysToUpdate.pop();
// create a reuseble JSON object
const stringifiedMessage = JSON.stringify({ type: `ontime-${key}`, payload: store[key] });
//and send it to all client then hanve not switch to the patch method
this.keyClients.forEach((ws) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(stringifiedMessage);
}
});
}
}

shutdown() {
this.wss?.close();
}
Expand Down
17 changes: 15 additions & 2 deletions apps/server/src/services/runtime-service/RuntimeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class RuntimeService {

/** last time we updated the socket */
static previousTimerUpdate: number;
static previousRuntimeUpdate: number;
static previousTimerValue: MaybeNumber; // previous timer value, could be null
static previousClockUpdate: number;

Expand All @@ -58,6 +59,7 @@ class RuntimeService {
this.eventTimer = eventTimer;

RuntimeService.previousTimerUpdate = -1;
RuntimeService.previousRuntimeUpdate = -1;
RuntimeService.previousTimerValue = -1;
RuntimeService.previousClockUpdate = -1;
RuntimeService.previousState = {} as RuntimeState;
Expand Down Expand Up @@ -678,10 +680,17 @@ function broadcastResult(_target: any, _propertyKey: string, descriptor: Propert
// we do the comparison by explicitly for each property
// to apply custom logic for different datasets

const shouldForceTimerUpdate = getForceUpdate(RuntimeService.previousTimerUpdate, state.clock); //FIXME: pause causess an avlache of update if timer is negative
const shouldForceTimerUpdate = getForceUpdate(
RuntimeService.previousTimerUpdate,
state.clock,
state.timer.playback,
);

const shouldUpdateTimer =
shouldForceTimerUpdate || getShouldTimerUpdate(RuntimeService.previousTimerValue, state.timer.current);

const shouldRuntimeUpdate = shouldUpdateTimer || getForceUpdate(RuntimeService.previousRuntimeUpdate, state.clock);

// some changes need an immediate update
const hasNewLoaded = state.eventNow?.id !== RuntimeService.previousState?.eventNow?.id;

Expand All @@ -702,9 +711,13 @@ function broadcastResult(_target: any, _propertyKey: string, descriptor: Propert
RuntimeService.previousState.timer = { ...state.timer };
}

if (hasChangedPlayback || (shouldUpdateTimer && !deepEqual(RuntimeService.previousState?.runtime, state.runtime))) {
if (
hasChangedPlayback ||
(shouldRuntimeUpdate && !deepEqual(RuntimeService.previousState?.runtime, state.runtime))
) {
eventStore.set('runtime', state.runtime);
RuntimeService.previousClockUpdate = state.clock;
RuntimeService.previousRuntimeUpdate = state.clock;
eventStore.set('clock', state.clock);
RuntimeService.previousState.runtime = { ...state.runtime };
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { millisToSeconds } from 'ontime-utils';

import { timerConfig } from '../../config/config.js';
import { MaybeNumber } from 'ontime-types';
import { MaybeNumber, Playback } from 'ontime-types';

/**
* Checks whether we should update the clock value
Expand Down Expand Up @@ -34,8 +34,10 @@ export function getShouldTimerUpdate(previousValue: number, currentValue: MaybeN
* In some cases we want to force an update to the timer
* - if the clock has slid back
* - if we have escaped the update rate (clock slid forward)
* - if we are not playing then there is no need to update the timer
*/
export function getForceUpdate(previousUpdate: number, now: number): boolean {
export function getForceUpdate(previousUpdate: number, now: number, playbackState: Playback = Playback.Play): boolean {
if (playbackState !== Playback.Play) return false;
const isClockBehind = now < previousUpdate;
const hasExceededRate = now - previousUpdate >= timerConfig.notificationRate;
return isClockBehind || hasExceededRate;
Expand Down
9 changes: 6 additions & 3 deletions apps/server/src/stores/EventStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type StoreGetter = <T extends keyof RuntimeStore>(key: T) => Partial<Runt

let store: Partial<RuntimeStore> = {};

const changedKeys = new Array<keyof RuntimeStore>();
const changedKeys = new Set<keyof RuntimeStore>();
let isUpdatePending: NodeJS.Immediate | null = null;
/**
* A runtime store that broadcasts its payload
Expand All @@ -27,13 +27,16 @@ export const eventStore = {
store[key] = value;

// check if the key is already marked for and update otherwise push it onto the update array
if (!changedKeys.includes(key)) changedKeys.push(key);
changedKeys.add(key);

//if there is already and update pending we don't need to schedule another one
if (!isUpdatePending) {
isUpdatePending = setImmediate(() => {
socket.sendRuntimeStoreUpdate(changedKeys, store);
for (const dataKey of changedKeys) {
socket.sendAsJson({ type: `ontime-${dataKey}`, payload: store[dataKey] });
}
isUpdatePending = null;
changedKeys.clear();
});
}
},
Expand Down

0 comments on commit 023b462

Please sign in to comment.