diff --git a/sequencing-server/src/app.ts b/sequencing-server/src/app.ts index 3c1f422a58..ff070d2c74 100644 --- a/sequencing-server/src/app.ts +++ b/sequencing-server/src/app.ts @@ -24,6 +24,10 @@ import getLogger from './utils/logger.js'; import { commandExpansionRouter } from './routes/command-expansion.js'; import { seqjsonRouter } from './routes/seqjson.js'; import { getHasuraSession, canUserPerformAction, ENDPOINTS_WHITELIST } from './utils/hasura.js'; +import type { Result } from '@nasa-jpl/aerie-ts-user-code-runner/build/utils/monads'; +import type { CacheItem, UserCodeError } from '@nasa-jpl/aerie-ts-user-code-runner'; +import { PromiseThrottler } from './utils/PromiseThrottler.js'; +import { backgroundTranspiler } from './backgroundTranspiler.js'; const logger = getLogger('app'); @@ -36,8 +40,17 @@ app.use(bodyParser.json({ limit: '100mb' })); DbExpansion.init(); export const db = DbExpansion.getDb(); +export let graphqlClient = new GraphQLClient(getEnv().MERLIN_GRAPHQL_URL, { + headers: { 'x-hasura-admin-secret': getEnv().HASURA_GRAPHQL_ADMIN_SECRET }, +}); +export const piscina = new Piscina({ + filename: new URL('worker.js', import.meta.url).pathname, + minThreads: parseInt(getEnv().SEQUENCING_WORKER_NUM), + resourceLimits: { maxOldGenerationSizeMb: parseInt(getEnv().SEQUENCING_MAX_WORKER_HEAP_MB) }, +}); +export const promiseThrottler = new PromiseThrottler(parseInt(getEnv().SEQUENCING_WORKER_NUM) - 2); +export const typeCheckingCache = new Map[]>>>(); -export const piscina = new Piscina({ filename: new URL('worker.js', import.meta.url).pathname }); const temporalPolyfillTypes = fs.readFileSync(new URL('TemporalPolyfillTypes.ts', import.meta.url).pathname, 'utf-8'); export type Context = { @@ -52,10 +65,6 @@ export type Context = { }; app.use(async (req: Request, res: Response, next: NextFunction) => { - const graphqlClient = new GraphQLClient(getEnv().MERLIN_GRAPHQL_URL, { - headers: { 'x-hasura-admin-secret': getEnv().HASURA_GRAPHQL_ADMIN_SECRET }, - }); - // Check and make sure the user making the request has the required permissions. if ( !ENDPOINTS_WHITELIST.has(req.url) && @@ -234,4 +243,23 @@ app.use((err: any, _: Request, res: Response, next: NextFunction) => { app.listen(PORT, () => { logger.info(`connected to port ${PORT}`); + logger.info(`Worker pool initialized: + Total workers started: ${piscina.threads.length}, + Heap Size per Worker: ${getEnv().SEQUENCING_MAX_WORKER_HEAP_MB} MB`); }); + +if (getEnv().TRANSPILER_ENABLED === 'true') { + //log that the tranpiler is on + logger.info(`Background Transpiler is 'on'`); + // Immediately call the background transpiler + await backgroundTranspiler(); + // Then continue calling it every 5 minutes + let transpilerInProgress: boolean = false; + setInterval(async () => { + if (!transpilerInProgress) { + transpilerInProgress = true; + await backgroundTranspiler(); + transpilerInProgress = false; + } + }, 60 * 5 * 1000); +}