aboutsummaryrefslogtreecommitdiff
path: root/src/server/DashSession/Session/agents/applied_session_agent.ts
blob: c42ba95cc78839b320f512a6ef6f707504d6ae26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import * as _cluster from 'cluster';
import { Monitor } from './monitor';
import { ServerWorker } from './server_worker';

const cluster = _cluster as any;
const isMaster = cluster.isPrimary;

export type ExitHandler = (reason: Error | boolean) => void | Promise<void>;

export abstract class AppliedSessionAgent {
    // the following two methods allow the developer to create a custom
    // session and use the built in customization options for each thread
    protected abstract initializeMonitor(monitor: Monitor): Promise<string>;
    protected abstract initializeServerWorker(): Promise<ServerWorker>;

    private launched = false;

    public killSession = (reason: string, graceful = true, errorCode = 0) => {
        const target = cluster.default.isPrimary ? this.sessionMonitor : this.serverWorker;
        target.killSession(reason, graceful, errorCode);
    };

    private sessionMonitorRef: Monitor | undefined;
    public get sessionMonitor(): Monitor {
        if (!cluster.default.isPrimary) {
            this.serverWorker.emit('kill', {
                graceful: false,
                reason: 'Cannot access the session monitor directly from the server worker thread.',
                errorCode: 1,
            });
            throw new Error();
        }
        return this.sessionMonitorRef!;
    }

    private serverWorkerRef: ServerWorker | undefined;
    public get serverWorker(): ServerWorker {
        if (isMaster) {
            throw new Error('Cannot access the server worker directly from the session monitor thread');
        }
        return this.serverWorkerRef!;
    }

    public async launch(): Promise<void> {
        if (!this.launched) {
            this.launched = true;
            if (isMaster) {
                this.sessionMonitorRef = Monitor.Create();
                const sessionKey = await this.initializeMonitor(this.sessionMonitorRef);
                this.sessionMonitorRef.finalize(sessionKey);
            } else {
                this.serverWorkerRef = await this.initializeServerWorker();
            }
        } else {
            throw new Error('Cannot launch a session thread more than once per process.');
        }
    }
}