chore: migrate to eslint 9
[poolifier.git] / examples / typescript / websocket-server-pool / ws-hybrid / src / websocket-server-worker.ts
CommitLineData
8ff2efc7 1import {
ded253e2 2 availableParallelism,
8ff2efc7 3 ClusterWorker,
3a502712 4 DynamicThreadPool,
8ff2efc7 5} from 'poolifier'
02999424 6import { type RawData, WebSocketServer } from 'ws'
ded253e2 7
02999424
JB
8import {
9 type ClusterWorkerData,
10 type ClusterWorkerResponse,
11 type DataPayload,
12 type MessagePayload,
8ff2efc7
JB
13 MessageType,
14 type ThreadWorkerData,
3a502712 15 type ThreadWorkerResponse,
02999424 16} from './types.js'
02999424
JB
17
18const emptyFunction = (): void => {
8ea47589 19 /* Intentional */
02999424
JB
20}
21
02999424 22class WebSocketServerWorker extends ClusterWorker<
3a502712
JB
23 ClusterWorkerData,
24 ClusterWorkerResponse
02999424 25> {
3d49c6d2
JB
26 private static wss: WebSocketServer
27 private static requestHandlerPool: DynamicThreadPool<
3a502712
JB
28 ThreadWorkerData<DataPayload>,
29 ThreadWorkerResponse<DataPayload>
3d49c6d2
JB
30 >
31
8ff2efc7
JB
32 private static readonly startWebSocketServer = (
33 workerData?: ClusterWorkerData
34 ): ClusterWorkerResponse => {
7d9756e3 35 const { port, workerFile, minWorkers, maxWorkers, ...poolOptions } =
3a502712 36 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67f3f2d6 37 workerData!
8ff2efc7 38
63ff88a9 39 WebSocketServerWorker.requestHandlerPool = new DynamicThreadPool<
3a502712
JB
40 ThreadWorkerData<DataPayload>,
41 ThreadWorkerResponse<DataPayload>
63ff88a9 42 >(
d0ed34c9
JB
43 minWorkers ?? 1,
44 maxWorkers ?? availableParallelism(),
45 workerFile,
7d9756e3 46 poolOptions
63ff88a9
JB
47 )
48
d0ed34c9
JB
49 WebSocketServerWorker.wss = new WebSocketServer({ port }, () => {
50 console.info(
51 `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port}/`
52 )
53 })
54
041dc05b 55 WebSocketServerWorker.wss.on('connection', ws => {
8ff2efc7
JB
56 ws.on('error', console.error)
57 ws.on('message', (message: RawData) => {
58 const { type, data } = JSON.parse(
8ff2efc7
JB
59 message.toString()
60 ) as MessagePayload<DataPayload>
61 switch (type) {
62 case MessageType.echo:
63ff88a9 63 WebSocketServerWorker.requestHandlerPool
8ff2efc7 64 .execute({ data }, 'echo')
041dc05b 65 .then(response => {
8ff2efc7
JB
66 ws.send(
67 JSON.stringify({
68 type: MessageType.echo,
3a502712 69 data: response.data,
8ff2efc7
JB
70 })
71 )
fefd3cef 72 return undefined
8ff2efc7
JB
73 })
74 .catch(emptyFunction)
75 break
76 case MessageType.factorial:
63ff88a9 77 WebSocketServerWorker.requestHandlerPool
8ff2efc7 78 .execute({ data }, 'factorial')
041dc05b 79 .then(response => {
8ff2efc7 80 ws.send(
66f0c14c
JB
81 JSON.stringify(
82 {
83 type: MessageType.factorial,
3a502712 84 data: response.data,
66f0c14c
JB
85 },
86 (_, v) => (typeof v === 'bigint' ? v.toString() : v)
87 )
8ff2efc7 88 )
fefd3cef 89 return undefined
8ff2efc7
JB
90 })
91 .catch(emptyFunction)
92 break
93 }
94 })
95 })
96 return {
97 status: true,
3a502712 98 port: WebSocketServerWorker.wss.options.port,
8ff2efc7
JB
99 }
100 }
101
02999424 102 public constructor () {
5daad283 103 super(WebSocketServerWorker.startWebSocketServer, {
cb5d91cf 104 killHandler: async () => {
cb5d91cf 105 await WebSocketServerWorker.requestHandlerPool.destroy()
93b097ac 106 WebSocketServerWorker.wss.close()
3a502712 107 },
5daad283 108 })
02999424
JB
109 }
110}
111
112export const webSocketServerWorker = new WebSocketServerWorker()