@contember/engine-server 2.1.0-beta.2 → 2.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"cluster.cjs","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":["timeout"],"mappings":";;;;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACDA,cAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAMA,MAAAA,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;;;;;"}
1
+ {"version":3,"file":"cluster.cjs","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils.js'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":["timeout"],"mappings":";;;;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACDA,cAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAMA,MAAAA,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"cluster.js","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACD,QAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAM,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;"}
1
+ {"version":3,"file":"cluster.js","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils.js'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACD,QAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAM,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"start.cjs","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":["createDefaultLogger","isDebugMode","getServerVersion","printStartInfo","resolveServerConfig","serverConfigSchema","createSentryLoggerHandler","os","getClusterProcessType","createContainer","listenOnProcessTermination","cluster","notifyWorkerStarted","WorkerManager","timeout"],"mappings":"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"}
1
+ {"version":3,"file":"start.cjs","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins.js'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils.js'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster.js'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":["createDefaultLogger","isDebugMode","getServerVersion","printStartInfo","resolveServerConfig","serverConfigSchema","createSentryLoggerHandler","os","getClusterProcessType","createContainer","listenOnProcessTermination","cluster","notifyWorkerStarted","WorkerManager","timeout"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":[],"mappings":";;;;;;;AAoBA,MAAM,SAAS,oBAAA;AACf,QAAQ,GAAG,WAAW,CAAA,YAAW;AAChC,SAAO,KAAK,OAAO;AACpB,CAAC;AAAA,CACC,YAAY;AACb,QAAM,UAAU,YAAA;AAEhB,QAAM,UAAU,MAAM,iBAAA;AACtB,iBAAe,EAAE,SAAS,QAAA,GAAW,MAAM;AAC3C,QAAM,UAAU,MAAM,YAAA;AACtB,QAAM,EAAE,cAAc,uBAAuB,qBAAA,IAAyB,MAAM,oBAAoB,EAAE,SAAS,oBAAoB;AAE/H,MAAI,QAAQ,KAAK,CAAC,MAAM,YAAY;AACnC,YAAQ,KAAK,CAAC;AAAA,EACf;AAEA,QAAM,gBAAgB,0BAA0B,aAAa,SAAS,QAAQ,GAAG;AACjF,MAAI,kBAAkB,MAAM;AAC3B,WAAO,WAAW,aAAa;AAAA,EAChC;AAEA,QAAM,eAAe,aAAa,eAAe;AAEjD,QAAM,cAAc,iBAAiB,SAAS,GAAG,OAAO,SAAS,OAAO,YAAY;AACpF,QAAM,gBAAgB,aAAa,gBAAgB;AAEnD,QAAM,cAAc,sBAAsB,aAAa;AAEvD,QAAM,YAAY,gBAAgB;AAAA,IACjC,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACA;AAED,MAAI,sBAAgC,CAAA;AACpC,QAAM,kBAAoC,CAAA;AAC1C,6BAA2B,iBAAiB,MAAM;AAElD,MAAI,QAAQ,UAAU;AACrB,UAAM,iBAAiB,aAAa;AACpC,UAAM,mBAAmB,UAAU,cAAc,OAAO,gBAAgB,MAAM;AAC7E,aAAO,KAAK,0CAA0C,cAAc,EAAE;AAAA,IACvE,CAAC;AACD,oBAAgB,KAAK,YAAY;AAChC,YAAM,IAAI,QAAa,CAAA,YAAW,iBAAiB,MAAM,OAAO,CAAC;AACjE,aAAO,KAAK,8BAA8B;AAAA,IAC3C,CAAC;AACD,QAAI,CAAC,aAAa,cAAc;AAC/B,4BAAsB,MAAM,UAAU,YAAY,WAAA;AAAA,IACnD;AAAA,EACD;AAEA,QAAM,OAAO,aAAa;AAC1B,QAAM,eAAe,MAAM;AAC1B,QAAI,aAAa,cAAc;AAC9B,aAAO,KAAK,yBAAyB;AAAA,IACtC,OAAO;AACN,aAAO,KAAK,6CAA6C,IAAI,EAAE;AAAA,IAChE;AACA,QAAI,oBAAoB,QAAQ;AAC/B,aAAO,KAAK,yBAAyB,oBAAoB,KAAK,IAAI,CAAC,EAAE;AAAA,IACtE;AAAA,EACD;AAEA,QAAM,mBAAmB,YAAY;AACpC,UAAM,oBAAoB,UAAU,YAAY,OAAA;AAChD,oBAAgB,KAAK,YAAY;AAChC,aAAO,MAAM,mBAAmB,MAAA;AAChC,aAAO,KAAK,uBAAuB;AAAA,IACpC,CAAC;AACD,UAAM;AAAA,EACP;AAEA,QAAM,cAAc,OAAO,eAAuB;AACjD,UAAM,SAAS,UAAU,mBAAmB,UAAU,UAAU;AAChE,UAAM,gBAAgB,OAAO,IAAI;AAAA,MAChC;AAAA,MACA,SAAS,CAAA,MAAK;AACb,eAAO,KAAK,CAAC;AACb,gBAAQ,KAAK,CAAC;AAAA,MACf;AAAA,IAAA,CACA;AACD,oBAAgB,KAAK,YAAY;AAC/B,OAAC,MAAM,eAAe,IAAA;AAAA,IACxB,CAAC;AACD,UAAM;AACN,WAAO,KAAK,oBAAoB,UAAU,WAAW;AAAA,EACtD;AAEA,QAAM,oBAAoB,aAAa;AACvC,MAAI,qBAAqB,sBAAsB,OAAO;AACrD,UAAM,YAAY,iBAAiB;AACnC,QAAI,eAAe;AAClB,0BAAA;AAAA,IACD;AAAA,EACD,WAAW,eAAe;AACzB,QAAI,QAAQ,UAAU;AACrB,aAAO,KAAK,UAAU,QAAQ,GAAG,aAAa;AAC9C,YAAM,gBAAgB,IAAI,cAAA;AAC1B,sBAAgB,KAAK,OAAO,EAAE,aAAa;AAC1C,cAAM,cAAc,UAAU,MAAM;AACpC,eAAO,KAAK,oBAAoB;AAAA,MACjC,CAAC;AAED,YAAM,cAAc,MAAM,EAAE,aAAa;AAEzC,UAAI,sBAAsB,OAAO;AAChC,mBAAW,cAAc,UAAU,mBAAmB,eAAA,GAAkB;AACvE,gBAAM,cAAc,MAAM;AAAA,YACzB;AAAA,YACA,KAAK;AAAA,cACJ,8BAA8B;AAAA,YAAA;AAAA,UAC/B,CACA;AAAA,QACF;AAAA,MACD;AACA,mBAAA;AAAA,IACD,OAAO;AACN,aAAO,KAAK,mBAAmB,QAAQ,GAAG,EAAE;AAG5C,cAAQ,GAAG,cAAc,MAAM,QAAQ,CAAC,CAAC;AAEzC,YAAM,iBAAA;AACN,0BAAA;AAAA,IACD;AAAA,EACD,OAAO;AACN,UAAM,iBAAA;AACN,QAAI,sBAAsB,OAAO;AAChC,iBAAW,cAAc,UAAU,mBAAmB,eAAA,GAAkB;AACvE,cAAM,YAAY,UAAU;AAAA,MAC7B;AAAA,IACD;AACA,iBAAA;AAAA,EACD;AACD,KAAK,MAAM,CAAA,MAAK;AACf,SAAO,KAAK,CAAC;AACb,UAAQ,KAAK,CAAC;AACf,CAAC;"}
1
+ {"version":3,"file":"start.js","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins.js'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils.js'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster.js'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cluster.cjs","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":["timeout"],"mappings":";;;;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACDA,cAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAMA,MAAAA,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;;;;;"}
1
+ {"version":3,"file":"cluster.cjs","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils.js'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":["timeout"],"mappings":";;;;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACDA,cAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAMA,MAAAA,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"cluster.js","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACD,QAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAM,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;"}
1
+ {"version":3,"file":"cluster.js","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils.js'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(\n\t\t\tArray.from(this.workers).map(async it => {\n\t\t\t\tif (!it) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\t\tit.disconnect()\n\t\t\t\tawait disconnectPromise\n\t\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\t\tit.kill(signal)\n\t\t\t\tawait killPromise\n\t\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t\t}),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAGO,MAAM,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEpB,MAAM,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AAC5B,YAAM,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AAC7D,eAAK;AACL,kBAAQ,IAAI;AACZ,iBAAO,eAAe,WAAW,QAAQ;AAAA,QAC1C;AAAA,MACD;AACA,YAAM,OAAO,GAAG,WAAW,QAAQ;AAAA,IACpC,CAAC;AAAA,IACD,QAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACR,cAAM,IAAI,MAAM,wBAAwB;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EAAA,CACD;AACF;AAEO,MAAM,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AACN,kBAAA,MAAQ,iBAAgB,KAAA;AAExB,kBAAA,MAAQ,+BAA2B,IAAA,CAAI;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACrC,YAAM,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,YAAY,KAAW;AACpC,UAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACzC,WAAK,QAAQ,OAAO,MAAM;AAC1B,UAAI,CAAC,KAAK,eAAe;AACxB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAM,QAAQ,GAAI;AAClB,cAAM,KAAK,YAAY,GAAG;AAAA,MAC3B;AAAA,IACD,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AACvB,UAAM,cAAc,QAAQ,IAAK;AAAA,EAClC;AAAA,EAEA,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACvB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IAChD;AACA,SAAK,gBAAgB;AACrB,UAAM,QAAQ;AAAA,MACb,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACxC,YAAI,CAAC,IAAI;AACR;AAAA,QACD;AACA,gBAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAClD,cAAM,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,WAAG,WAAA;AACH,cAAM;AACN,cAAM,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,WAAG,KAAK,MAAM;AACd,cAAM;AACN,gBAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,MAClD,CAAC;AAAA,IAAA;AAAA,EAEH;AACD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"start.cjs","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":["createDefaultLogger","isDebugMode","getServerVersion","printStartInfo","resolveServerConfig","serverConfigSchema","createSentryLoggerHandler","os","getClusterProcessType","createContainer","listenOnProcessTermination","cluster","notifyWorkerStarted","WorkerManager","timeout"],"mappings":"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"}
1
+ {"version":3,"file":"start.cjs","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins.js'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils.js'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster.js'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":["createDefaultLogger","isDebugMode","getServerVersion","printStartInfo","resolveServerConfig","serverConfigSchema","createSentryLoggerHandler","os","getClusterProcessType","createContainer","listenOnProcessTermination","cluster","notifyWorkerStarted","WorkerManager","timeout"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"start.js","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins.js'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils.js'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster.js'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t;(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount,\n\t\t\t\t\t\tenv: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":[],"mappings":"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"}