11import express from 'express' ;
22import path from 'path' ;
33import http from 'http' ;
4+ import { Server } from "socket.io" ;
45import cors from 'cors' ;
56import dotenv from 'dotenv' ;
67dotenv . config ( ) ;
@@ -10,7 +11,6 @@ import logger from './logger';
1011import { connectDB , syncDB } from './storage/db'
1112import cookieParser from 'cookie-parser' ;
1213import { SERVER_PORT } from "./constants/config" ;
13- import { Server } from "socket.io" ;
1414import { readdirSync } from "fs"
1515import { fork } from 'child_process' ;
1616import { capture } from "./utils/analytics" ;
@@ -75,9 +75,8 @@ const server = http.createServer(app);
7575
7676/**
7777 * Globally exported singleton instance of socket.io for socket communication with the client.
78- * @type {Server }
7978 */
80- export const io = new Server ( server ) ;
79+ export let io : Server ;
8180
8281/**
8382 * {@link BrowserPool } globally exported singleton instance for managing browsers.
@@ -112,34 +111,6 @@ const recordingWorkerPath = path.resolve(__dirname, isProduction ? './pgboss-wor
112111let workerProcess : any ;
113112let recordingWorkerProcess : any ;
114113
115- if ( ! isProduction ) {
116- workerProcess = fork ( workerPath , [ ] , {
117- execArgv : [ '--inspect=5859' ] ,
118- } ) ;
119- workerProcess . on ( 'message' , ( message : any ) => {
120- console . log ( `Message from worker: ${ message } ` ) ;
121- } ) ;
122- workerProcess . on ( 'error' , ( error : any ) => {
123- console . error ( `Error in worker: ${ error } ` ) ;
124- } ) ;
125- workerProcess . on ( 'exit' , ( code : any ) => {
126- console . log ( `Worker exited with code: ${ code } ` ) ;
127- } ) ;
128-
129- recordingWorkerProcess = fork ( recordingWorkerPath , [ ] , {
130- execArgv : [ '--inspect=5860' ] ,
131- } ) ;
132- recordingWorkerProcess . on ( 'message' , ( message : any ) => {
133- console . log ( `Message from recording worker: ${ message } ` ) ;
134- } ) ;
135- recordingWorkerProcess . on ( 'error' , ( error : any ) => {
136- console . error ( `Error in recording worker: ${ error } ` ) ;
137- } ) ;
138- recordingWorkerProcess . on ( 'exit' , ( code : any ) => {
139- console . log ( `Recording worker exited with code: ${ code } ` ) ;
140- } ) ;
141- }
142-
143114app . get ( '/' , function ( req , res ) {
144115 capture (
145116 'maxun-oss-server-run' , {
@@ -160,66 +131,113 @@ app.use((req, res, next) => {
160131 next ( ) ;
161132} ) ;
162133
163- io . of ( '/queued-run' ) . on ( 'connection' , ( socket ) => {
164- const userId = socket . handshake . query . userId as string ;
165-
166- if ( userId ) {
167- socket . join ( `user-${ userId } ` ) ;
168- logger . log ( 'info' , `Client joined queued-run namespace for user: ${ userId } , socket: ${ socket . id } ` ) ;
169-
170- socket . on ( 'disconnect' , ( ) => {
171- logger . log ( 'info' , `Client disconnected from queued-run namespace: ${ socket . id } ` ) ;
172- } ) ;
173- } else {
174- logger . log ( 'warn' , `Client connected to queued-run namespace without userId: ${ socket . id } ` ) ;
175- socket . disconnect ( ) ;
176- }
177- } ) ;
178-
179- setInterval ( ( ) => {
180- processQueuedRuns ( ) ;
181- } , 5000 ) ;
182-
183-
184- server . listen ( SERVER_PORT , '0.0.0.0' , async ( ) => {
185- try {
186- await connectDB ( ) ;
187- await syncDB ( ) ;
188- logger . log ( 'info' , `Server listening on port ${ SERVER_PORT } ` ) ;
189- } catch ( error : any ) {
190- logger . log ( 'error' , `Failed to connect to the database: ${ error . message } ` ) ;
191- process . exit ( 1 ) ;
192- }
193- } ) ;
134+ if ( require . main === module ) {
135+ setInterval ( ( ) => {
136+ processQueuedRuns ( ) ;
137+ } , 5000 ) ;
138+ }
194139
195- process . on ( 'SIGINT' , async ( ) => {
196- console . log ( 'Main app shutting down...' ) ;
197- try {
198- await Run . update (
199- {
200- status : 'failed' ,
201- finishedAt : new Date ( ) . toLocaleString ( ) ,
202- log : 'Process interrupted during execution - worker shutdown'
203- } ,
204- {
205- where : { status : 'running' }
140+ if ( require . main === module ) {
141+ server . listen ( SERVER_PORT , '0.0.0.0' , async ( ) => {
142+ try {
143+ await connectDB ( ) ;
144+ await syncDB ( ) ;
145+
146+ io = new Server ( server ) ;
147+
148+ io . of ( '/queued-run' ) . on ( 'connection' , ( socket ) => {
149+ const userId = socket . handshake . query . userId as string ;
150+
151+ if ( userId ) {
152+ socket . join ( `user-${ userId } ` ) ;
153+ logger . log ( 'info' , `Client joined queued-run namespace for user: ${ userId } , socket: ${ socket . id } ` ) ;
154+
155+ socket . on ( 'disconnect' , ( ) => {
156+ logger . log ( 'info' , `Client disconnected from queued-run namespace: ${ socket . id } ` ) ;
157+ } ) ;
158+ } else {
159+ logger . log ( 'warn' , `Client connected to queued-run namespace without userId: ${ socket . id } ` ) ;
160+ socket . disconnect ( ) ;
161+ }
162+ } ) ;
163+
164+ if ( ! isProduction ) {
165+ if ( process . platform === 'win32' ) {
166+ workerProcess = fork ( workerPath , [ ] , {
167+ execArgv : [ '--inspect=5859' ] ,
168+ } ) ;
169+ workerProcess . on ( 'message' , ( message : any ) => {
170+ console . log ( `Message from worker: ${ message } ` ) ;
171+ } ) ;
172+ workerProcess . on ( 'error' , ( error : any ) => {
173+ console . error ( `Error in worker: ${ error } ` ) ;
174+ } ) ;
175+ workerProcess . on ( 'exit' , ( code : any ) => {
176+ console . log ( `Worker exited with code: ${ code } ` ) ;
177+ } ) ;
178+
179+ recordingWorkerProcess = fork ( recordingWorkerPath , [ ] , {
180+ execArgv : [ '--inspect=5860' ] ,
181+ } ) ;
182+ recordingWorkerProcess . on ( 'message' , ( message : any ) => {
183+ console . log ( `Message from recording worker: ${ message } ` ) ;
184+ } ) ;
185+ recordingWorkerProcess . on ( 'error' , ( error : any ) => {
186+ console . error ( `Error in recording worker: ${ error } ` ) ;
187+ } ) ;
188+ recordingWorkerProcess . on ( 'exit' , ( code : any ) => {
189+ console . log ( `Recording worker exited with code: ${ code } ` ) ;
190+ } ) ;
191+ } else {
192+ // Run in same process for non-Windows
193+ try {
194+ await import ( './schedule-worker' ) ;
195+ await import ( './pgboss-worker' ) ;
196+ console . log ( 'Workers started in main process for memory sharing' ) ;
197+ } catch ( error ) {
198+ console . error ( 'Failed to start workers in main process:' , error ) ;
199+ }
200+ }
206201 }
207- ) ;
208- } catch ( error : any ) {
209- console . error ( 'Error updating runs:' , error ) ;
210- }
202+
203+ logger . log ( 'info' , `Server listening on port ${ SERVER_PORT } ` ) ;
204+ } catch ( error : any ) {
205+ logger . log ( 'error' , `Failed to connect to the database: ${ error . message } ` ) ;
206+ process . exit ( 1 ) ;
207+ }
208+ } ) ;
209+ }
211210
212- try {
213- console . log ( 'Closing PostgreSQL connection pool...' ) ;
214- await pool . end ( ) ;
215- console . log ( 'PostgreSQL connection pool closed' ) ;
216- } catch ( error ) {
217- console . error ( 'Error closing PostgreSQL connection pool:' , error ) ;
218- }
211+ if ( require . main === module ) {
212+ process . on ( 'SIGINT' , async ( ) => {
213+ console . log ( 'Main app shutting down...' ) ;
214+ try {
215+ await Run . update (
216+ {
217+ status : 'failed' ,
218+ finishedAt : new Date ( ) . toLocaleString ( ) ,
219+ log : 'Process interrupted during execution - worker shutdown'
220+ } ,
221+ {
222+ where : { status : 'running' }
223+ }
224+ ) ;
225+ } catch ( error : any ) {
226+ console . error ( 'Error updating runs:' , error ) ;
227+ }
219228
220- if ( ! isProduction ) {
221- if ( workerProcess ) workerProcess . kill ( ) ;
222- if ( recordingWorkerProcess ) recordingWorkerProcess . kill ( ) ;
223- }
224- process . exit ( ) ;
225- } ) ;
229+ try {
230+ console . log ( 'Closing PostgreSQL connection pool...' ) ;
231+ await pool . end ( ) ;
232+ console . log ( 'PostgreSQL connection pool closed' ) ;
233+ } catch ( error ) {
234+ console . error ( 'Error closing PostgreSQL connection pool:' , error ) ;
235+ }
236+
237+ if ( ! isProduction && process . platform === 'win32' ) {
238+ if ( workerProcess ) workerProcess . kill ( ) ;
239+ if ( recordingWorkerProcess ) recordingWorkerProcess . kill ( ) ;
240+ }
241+ process . exit ( ) ;
242+ } ) ;
243+ }
0 commit comments