Skip to content

Commit

Permalink
server: hook cluster creation for electron
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Feb 5, 2025
1 parent 07baddc commit 05cb505
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
4 changes: 2 additions & 2 deletions server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 25 additions & 11 deletions server/src/scrypted-cluster-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { computeClusterObjectHash } from './cluster/cluster-hash';
import { getClusterLabels, getClusterWorkerWeight } from './cluster/cluster-labels';
import { getScryptedClusterMode, InitializeCluster, setupCluster } from './cluster/cluster-setup';
import type { ClusterObject } from './cluster/connect-rpc-object';
import { getScryptedFFmpegPath } from './plugin/ffmpeg-path';
import { getPluginVolume, getScryptedVolume } from './plugin/plugin-volume';
import { prepareZip } from './plugin/runtime/node-worker-common';
import { getBuiltinRuntimeHosts } from './plugin/runtime/runtime-host';
Expand All @@ -23,15 +24,20 @@ import { EnvControl } from './services/env';
import { Info } from './services/info';
import { ServiceControl } from './services/service-control';
import { sleep } from './sleep';
import { getScryptedFFmpegPath } from './plugin/ffmpeg-path';

installSourceMapSupport({
environment: 'node',
});

async function start(mainFilename: string, serviceControl?: ServiceControl) {
serviceControl ||= new ServiceControl();
startClusterClient(mainFilename, serviceControl);
async function start(mainFilename: string, options?: {
onClusterWorkerCreated?: (options?: {
clusterPluginHosts?: ReturnType<typeof getBuiltinRuntimeHosts>,
}) => Promise<void>,
serviceControl?: ServiceControl;
}) {
options ||= {};
options.serviceControl ||= new ServiceControl();
startClusterClient(mainFilename, options);
}

export default start;
Expand Down Expand Up @@ -122,12 +128,11 @@ export interface ClusterForkResultInterface {

export type ClusterForkParam = (runtime: string, options: RuntimeWorkerOptions, peerLiveness: PeerLiveness, getZip: () => Promise<Buffer>) => Promise<ClusterForkResultInterface>;

function createClusterForkParam(mainFilename: string, clusterId: string, clusterSecret: string, clusterWorkerId: string) {
function createClusterForkParam(mainFilename: string, clusterId: string, clusterSecret: string, clusterWorkerId: string, clusterPluginHosts: ReturnType<typeof getBuiltinRuntimeHosts>) {
const clusterForkParam: ClusterForkParam = async (runtime, runtimeWorkerOptions, peerLiveness, getZip) => {
let runtimeWorker: RuntimeWorker;

const builtins = getBuiltinRuntimeHosts();
const rt = builtins.get(runtime);
const rt = clusterPluginHosts.get(runtime);
if (!rt)
throw new Error('unknown runtime ' + runtime);

Expand Down Expand Up @@ -205,7 +210,12 @@ function createClusterForkParam(mainFilename: string, clusterId: string, cluster
return clusterForkParam;
}

export function startClusterClient(mainFilename: string, serviceControl?: ServiceControl) {
export function startClusterClient(mainFilename: string, options?: {
onClusterWorkerCreated?: (options?: {
clusterPluginHosts?: ReturnType<typeof getBuiltinRuntimeHosts>,
}) => Promise<void>,
serviceControl?: ServiceControl;
}) {
console.log('Cluster client starting.');

const envControl = new EnvControl();
Expand All @@ -217,6 +227,10 @@ export function startClusterClient(mainFilename: string, serviceControl?: Servic
const clusterSecret = process.env.SCRYPTED_CLUSTER_SECRET;
const clusterMode = getScryptedClusterMode();
const [, host, port] = clusterMode;

const clusterPluginHosts = getBuiltinRuntimeHosts();
options?.onClusterWorkerCreated?.({ clusterPluginHosts });

(async () => {
while (true) {
// this sleep is here to prevent a tight loop if the server is down.
Expand Down Expand Up @@ -259,7 +273,7 @@ export function startClusterClient(mainFilename: string, serviceControl?: Servic
process.env.SCRYPTED_CLUSTER_ADDRESS = socket.localAddress;

const peer = preparePeer(socket, 'client');
peer.params['service-control'] = serviceControl;
peer.params['service-control'] = options?.serviceControl;
peer.params['env-control'] = envControl;
peer.params['info'] = new Info();
peer.params['fs.promises'] = {
Expand Down Expand Up @@ -294,7 +308,7 @@ export function startClusterClient(mainFilename: string, serviceControl?: Servic
const clusterPeerSetup = setupCluster(peer);
await clusterPeerSetup.initializeCluster({ clusterId, clusterSecret, clusterWorkerId });

peer.params['fork'] = createClusterForkParam(mainFilename, clusterId, clusterSecret, clusterWorkerId);
peer.params['fork'] = createClusterForkParam(mainFilename, clusterId, clusterSecret, clusterWorkerId, clusterPluginHosts);

await peer.killed;
}
Expand All @@ -316,7 +330,7 @@ export function createClusterServer(mainFilename: string, scryptedRuntime: Scryp
labels: getClusterLabels(),
id: scryptedRuntime.serverClusterWorkerId,
peer: undefined,
fork: Promise.resolve(createClusterForkParam(mainFilename, scryptedRuntime.clusterId, scryptedRuntime.clusterSecret, scryptedRuntime.serverClusterWorkerId)),
fork: Promise.resolve(createClusterForkParam(mainFilename, scryptedRuntime.clusterId, scryptedRuntime.clusterSecret, scryptedRuntime.serverClusterWorkerId, scryptedRuntime.pluginHosts)),
name: process.env.SCRYPTED_CLUSTER_WORKER_NAME || os.hostname(),
address: process.env.SCRYPTED_CLUSTER_ADDRESS,
weight: getClusterWorkerWeight(),
Expand Down
4 changes: 4 additions & 0 deletions server/src/scrypted-main-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import vm from 'vm';
import { getScryptedClusterMode } from './cluster/cluster-setup';
import { PluginError } from './plugin/plugin-error';
import { isNodePluginWorkerProcess } from './plugin/runtime/node-fork-worker';
import type { getBuiltinRuntimeHosts } from './plugin/runtime/runtime-host';
import { RPCResultError, startPeriodicGarbageCollection } from './rpc';
import type { Runtime } from './scrypted-server-main';
import { getDotEnvPath } from './services/env';
Expand All @@ -16,6 +17,9 @@ import type { ServiceControl } from './services/service-control';
function start(mainFilename: string, options?: {
serviceControl?: ServiceControl,
onRuntimeCreated?: (runtime: Runtime) => Promise<void>,
onClusterWorkerCreated?: (options?: {
clusterPluginHosts?: ReturnType<typeof getBuiltinRuntimeHosts>,
}) => Promise<void>,
}) {
// Allow including a custom file path for platforms that require
// compatibility hacks. For example, Android may need to patch
Expand Down

0 comments on commit 05cb505

Please sign in to comment.