nmtjs 0.16.0-beta.9 → 0.16.0
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.
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/entrypoints/worker.js +9 -9
- package/dist/entrypoints/worker.js.map +1 -1
- package/dist/index.d.ts +14 -11
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/runtime/application/index.d.ts +1 -5
- package/dist/runtime/application/index.js +1 -5
- package/dist/runtime/application/index.js.map +1 -1
- package/dist/runtime/enums.d.ts +1 -12
- package/dist/runtime/enums.js +1 -14
- package/dist/runtime/enums.js.map +1 -1
- package/dist/runtime/hooks.d.ts +1 -4
- package/dist/runtime/hooks.js +1 -3
- package/dist/runtime/hooks.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -3
- package/dist/runtime/index.js +1 -3
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/injectables.d.ts +3 -3
- package/dist/runtime/jobs/job.d.ts +1 -2
- package/dist/runtime/jobs/job.js.map +1 -1
- package/dist/runtime/jobs/router.d.ts +2 -5
- package/dist/runtime/jobs/router.js +2 -3
- package/dist/runtime/jobs/router.js.map +1 -1
- package/dist/runtime/jobs/runner.d.ts +1 -1
- package/dist/runtime/jobs/runner.js +1 -1
- package/dist/runtime/jobs/runner.js.map +1 -1
- package/dist/runtime/jobs/types.d.ts +1 -1
- package/dist/runtime/metrics/metric.d.ts +2 -2
- package/dist/runtime/metrics/metric.js +1 -1
- package/dist/runtime/metrics/metric.js.map +1 -1
- package/dist/runtime/metrics/registry.d.ts +3 -3
- package/dist/runtime/metrics/registry.js +1 -1
- package/dist/runtime/metrics/registry.js.map +1 -1
- package/dist/runtime/metrics/server.js +1 -1
- package/dist/runtime/metrics/server.js.map +1 -1
- package/dist/runtime/plugin.d.ts +2 -8
- package/dist/runtime/plugin.js +1 -3
- package/dist/runtime/plugin.js.map +1 -1
- package/dist/runtime/runtime.d.ts +2 -2
- package/dist/runtime/runtime.js +1 -2
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/server/applications.js +3 -0
- package/dist/runtime/server/applications.js.map +1 -1
- package/dist/runtime/server/config.d.ts +15 -12
- package/dist/runtime/server/config.js.map +1 -1
- package/dist/runtime/server/jobs.d.ts +6 -7
- package/dist/runtime/server/jobs.js +44 -30
- package/dist/runtime/server/jobs.js.map +1 -1
- package/dist/runtime/subscription/redis.d.ts +1 -1
- package/dist/runtime/subscription/redis.js.map +1 -1
- package/dist/runtime/types.d.ts +3 -11
- package/dist/runtime/workers/application.d.ts +15 -33
- package/dist/runtime/workers/application.js +46 -139
- package/dist/runtime/workers/application.js.map +1 -1
- package/dist/runtime/workers/job.js +2 -1
- package/dist/runtime/workers/job.js.map +1 -1
- package/dist/vite/server.js +1 -1
- package/dist/vite/server.js.map +1 -1
- package/package.json +19 -14
- package/src/cli.ts +2 -3
- package/src/entrypoints/worker.ts +11 -9
- package/src/index.ts +12 -5
- package/src/runtime/application/index.ts +1 -5
- package/src/runtime/enums.ts +2 -14
- package/src/runtime/hooks.ts +1 -5
- package/src/runtime/index.ts +2 -3
- package/src/runtime/injectables.ts +2 -2
- package/src/runtime/jobs/job.ts +1 -2
- package/src/runtime/jobs/router.ts +12 -15
- package/src/runtime/jobs/runner.ts +2 -2
- package/src/runtime/jobs/types.ts +1 -1
- package/src/runtime/metrics/metric.ts +2 -2
- package/src/runtime/metrics/registry.ts +5 -1
- package/src/runtime/metrics/server.ts +1 -1
- package/src/runtime/plugin.ts +2 -13
- package/src/runtime/runtime.ts +2 -4
- package/src/runtime/server/applications.ts +6 -0
- package/src/runtime/server/config.ts +27 -21
- package/src/runtime/server/jobs.ts +58 -34
- package/src/runtime/subscription/redis.ts +1 -1
- package/src/runtime/types.ts +3 -12
- package/src/runtime/workers/application.ts +76 -160
- package/src/runtime/workers/job.ts +3 -6
- package/src/vite/server.ts +1 -1
- package/dist/runtime/application/api/api.d.ts +0 -55
- package/dist/runtime/application/api/api.js +0 -252
- package/dist/runtime/application/api/api.js.map +0 -1
- package/dist/runtime/application/api/config.d.ts +0 -14
- package/dist/runtime/application/api/config.js +0 -6
- package/dist/runtime/application/api/config.js.map +0 -1
- package/dist/runtime/application/api/constants.d.ts +0 -14
- package/dist/runtime/application/api/constants.js +0 -8
- package/dist/runtime/application/api/constants.js.map +0 -1
- package/dist/runtime/application/api/filters.d.ts +0 -14
- package/dist/runtime/application/api/filters.js +0 -11
- package/dist/runtime/application/api/filters.js.map +0 -1
- package/dist/runtime/application/api/guards.d.ts +0 -15
- package/dist/runtime/application/api/guards.js +0 -8
- package/dist/runtime/application/api/guards.js.map +0 -1
- package/dist/runtime/application/api/index.d.ts +0 -23
- package/dist/runtime/application/api/index.js +0 -17
- package/dist/runtime/application/api/index.js.map +0 -1
- package/dist/runtime/application/api/logging.d.ts +0 -14
- package/dist/runtime/application/api/logging.js +0 -77
- package/dist/runtime/application/api/logging.js.map +0 -1
- package/dist/runtime/application/api/meta.d.ts +0 -21
- package/dist/runtime/application/api/meta.js +0 -2
- package/dist/runtime/application/api/meta.js.map +0 -1
- package/dist/runtime/application/api/middlewares.d.ts +0 -14
- package/dist/runtime/application/api/middlewares.js +0 -12
- package/dist/runtime/application/api/middlewares.js.map +0 -1
- package/dist/runtime/application/api/procedure.d.ts +0 -71
- package/dist/runtime/application/api/procedure.js +0 -41
- package/dist/runtime/application/api/procedure.js.map +0 -1
- package/dist/runtime/application/api/router.d.ts +0 -93
- package/dist/runtime/application/api/router.js +0 -55
- package/dist/runtime/application/api/router.js.map +0 -1
- package/dist/runtime/application/api/types.d.ts +0 -38
- package/dist/runtime/application/api/types.js +0 -2
- package/dist/runtime/application/api/types.js.map +0 -1
- package/dist/runtime/application/config.d.ts +0 -28
- package/dist/runtime/application/config.js +0 -25
- package/dist/runtime/application/config.js.map +0 -1
- package/dist/runtime/application/constants.d.ts +0 -2
- package/dist/runtime/application/constants.js +0 -2
- package/dist/runtime/application/constants.js.map +0 -1
- package/dist/runtime/application/hook.d.ts +0 -19
- package/dist/runtime/application/hook.js +0 -11
- package/dist/runtime/application/hook.js.map +0 -1
- package/dist/runtime/application/hooks.d.ts +0 -3
- package/dist/runtime/application/hooks.js +0 -4
- package/dist/runtime/application/hooks.js.map +0 -1
- package/src/runtime/application/api/api.ts +0 -406
- package/src/runtime/application/api/config.ts +0 -18
- package/src/runtime/application/api/constants.ts +0 -22
- package/src/runtime/application/api/filters.ts +0 -39
- package/src/runtime/application/api/guards.ts +0 -33
- package/src/runtime/application/api/index.ts +0 -69
- package/src/runtime/application/api/logging.ts +0 -110
- package/src/runtime/application/api/meta.ts +0 -37
- package/src/runtime/application/api/middlewares.ts +0 -37
- package/src/runtime/application/api/procedure.ts +0 -224
- package/src/runtime/application/api/router.ts +0 -247
- package/src/runtime/application/api/types.ts +0 -138
- package/src/runtime/application/config.ts +0 -82
- package/src/runtime/application/constants.ts +0 -4
- package/src/runtime/application/hook.ts +0 -51
- package/src/runtime/application/hooks.ts +0 -3
|
@@ -1,26 +1,23 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnyGuard,
|
|
3
|
+
AnyMiddleware,
|
|
4
|
+
AnyProcedure,
|
|
5
|
+
AnyRouter,
|
|
6
|
+
AnyRouterMetaBinding,
|
|
7
|
+
ProcedureMetaBinding,
|
|
8
|
+
Router,
|
|
9
|
+
} from '@nmtjs/application'
|
|
1
10
|
import type { MaybePromise } from '@nmtjs/common'
|
|
2
11
|
import type { TProcedureContract, TRouterContract } from '@nmtjs/contract'
|
|
3
12
|
import type { Dependencies, DependencyContext } from '@nmtjs/core'
|
|
4
13
|
import type { NullableType, OptionalType } from '@nmtjs/type'
|
|
5
14
|
import type { NeverType } from '@nmtjs/type/never'
|
|
15
|
+
import { createProcedure, createRouter } from '@nmtjs/application'
|
|
6
16
|
import { CoreInjectables } from '@nmtjs/core'
|
|
7
17
|
import { t } from '@nmtjs/type'
|
|
8
18
|
|
|
9
|
-
import type { AnyGuard } from '../application/api/guards.ts'
|
|
10
|
-
import type { AnyMiddleware } from '../application/api/middlewares.ts'
|
|
11
|
-
import type {
|
|
12
|
-
AnyProcedure,
|
|
13
|
-
ProcedureMetaBinding,
|
|
14
|
-
} from '../application/api/procedure.ts'
|
|
15
|
-
import type {
|
|
16
|
-
AnyRouter,
|
|
17
|
-
AnyRouterMetaBinding,
|
|
18
|
-
Router,
|
|
19
|
-
} from '../application/api/router.ts'
|
|
20
19
|
import type { AnyJob } from './job.ts'
|
|
21
20
|
import type { JobStatus } from './types.ts'
|
|
22
|
-
import { createProcedure } from '../application/api/procedure.ts'
|
|
23
|
-
import { createRouter } from '../application/api/router.ts'
|
|
24
21
|
import { jobManager } from '../injectables.ts'
|
|
25
22
|
|
|
26
23
|
// ============================================================================
|
|
@@ -196,7 +193,7 @@ type JobItemSchemaType<T extends AnyJob> = t.ObjectType<{
|
|
|
196
193
|
startedAt: OptionalType<t.NumberType>
|
|
197
194
|
completedAt: OptionalType<t.NumberType>
|
|
198
195
|
error: OptionalType<t.StringType>
|
|
199
|
-
stacktrace:
|
|
196
|
+
stacktrace: NullableType<t.ArrayType<t.StringType>>
|
|
200
197
|
}>
|
|
201
198
|
|
|
202
199
|
/** Type-level representation of createListOutputSchema output */
|
|
@@ -326,7 +323,7 @@ function createJobItemSchema<T extends AnyJob>(job: T): JobItemSchemaType<T> {
|
|
|
326
323
|
startedAt: t.number().optional(),
|
|
327
324
|
completedAt: t.number().optional(),
|
|
328
325
|
error: t.string().optional(),
|
|
329
|
-
stacktrace: t.array(t.string()).
|
|
326
|
+
stacktrace: t.array(t.string()).nullable(),
|
|
330
327
|
})
|
|
331
328
|
}
|
|
332
329
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { LifecycleHooks } from '@nmtjs/application'
|
|
1
2
|
import type { Container, Logger, LoggingOptions } from '@nmtjs/core'
|
|
2
3
|
import type { Job } from 'bullmq'
|
|
4
|
+
import { LifecycleHook } from '@nmtjs/application'
|
|
3
5
|
import { anyAbortSignal } from '@nmtjs/common'
|
|
4
6
|
import { Scope } from '@nmtjs/core'
|
|
5
7
|
import { UnrecoverableError } from 'bullmq'
|
|
6
8
|
|
|
7
|
-
import type { LifecycleHooks } from '../hooks.ts'
|
|
8
9
|
import type { AnyJob } from './job.ts'
|
|
9
10
|
import type { AnyJobStep } from './step.ts'
|
|
10
11
|
import type {
|
|
@@ -12,7 +13,6 @@ import type {
|
|
|
12
13
|
JobProgressCheckpoint,
|
|
13
14
|
StepResultEntry,
|
|
14
15
|
} from './types.ts'
|
|
15
|
-
import { LifecycleHook } from '../enums.ts'
|
|
16
16
|
import {
|
|
17
17
|
currentJobInfo,
|
|
18
18
|
jobAbortSignal,
|
|
@@ -105,7 +105,7 @@ export interface JobItem<TInput = unknown, TOutput = unknown> {
|
|
|
105
105
|
/** Error message if job failed */
|
|
106
106
|
error?: string
|
|
107
107
|
/** Stack trace if job failed */
|
|
108
|
-
stacktrace
|
|
108
|
+
stacktrace: string[] | null
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// ============================================================================
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ClassConstructorArgs } from '@nmtjs/common'
|
|
2
|
-
import type { Metric, MetricConfiguration } from 'prom-client'
|
|
3
|
-
import { Counter, Gauge, Histogram, Summary } from 'prom-client'
|
|
2
|
+
import type { Metric, MetricConfiguration } from '@nmtjs/prom-client'
|
|
3
|
+
import { Counter, Gauge, Histogram, Summary } from '@nmtjs/prom-client'
|
|
4
4
|
|
|
5
5
|
import { registry } from './registry.ts'
|
|
6
6
|
|
package/src/runtime/plugin.ts
CHANGED
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { LifecycleHooks } from './hooks.ts'
|
|
4
|
-
|
|
5
|
-
export interface RuntimePlugin {
|
|
6
|
-
name: string
|
|
7
|
-
hooks?: LifecycleHooks['_']['config']
|
|
8
|
-
injections?: Provision[]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function createPlugin<T extends RuntimePlugin>(plugin: T): T {
|
|
12
|
-
return plugin
|
|
13
|
-
}
|
|
1
|
+
export type { RuntimePlugin } from '@nmtjs/application'
|
|
2
|
+
export { createPlugin } from '@nmtjs/application'
|
package/src/runtime/runtime.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import type { RuntimePlugin } from '@nmtjs/application'
|
|
1
2
|
import type {
|
|
2
3
|
AnyInjectable,
|
|
3
4
|
Dependant,
|
|
4
5
|
Logger,
|
|
5
6
|
LoggingOptions,
|
|
6
7
|
} from '@nmtjs/core'
|
|
8
|
+
import { LifecycleHook, LifecycleHooks } from '@nmtjs/application'
|
|
7
9
|
import {
|
|
8
10
|
Container,
|
|
9
11
|
createLogger,
|
|
@@ -11,10 +13,6 @@ import {
|
|
|
11
13
|
Scope,
|
|
12
14
|
} from '@nmtjs/core'
|
|
13
15
|
|
|
14
|
-
import type { RuntimePlugin } from './plugin.ts'
|
|
15
|
-
import { LifecycleHook } from './enums.ts'
|
|
16
|
-
import { LifecycleHooks } from './hooks.ts'
|
|
17
|
-
|
|
18
16
|
export type BaseRuntimeOptions = {
|
|
19
17
|
logger?: LoggingOptions
|
|
20
18
|
container?: Container
|
|
@@ -120,6 +120,12 @@ export class ApplicationServerApplications extends EventEmitter<{
|
|
|
120
120
|
|
|
121
121
|
// Add workers to the pool
|
|
122
122
|
for (let i = 0; i < threadsConfig.length; i++) {
|
|
123
|
+
if (applicationPath.type !== 'neemata') {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Unsupported custom application worker: ${applicationName}`,
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
123
129
|
const workerData = {
|
|
124
130
|
runtime: {
|
|
125
131
|
type: 'application',
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ApplicationHost,
|
|
3
|
+
ApplicationHostDefinition,
|
|
4
|
+
TransportOptionsOf,
|
|
5
|
+
} from '@nmtjs/application'
|
|
1
6
|
import type { LoggingOptions } from '@nmtjs/core'
|
|
2
|
-
import type { Transport } from '@nmtjs/gateway'
|
|
3
7
|
import type { ApplicationOptions } from '@nmtjs/proxy'
|
|
4
8
|
import type { Applications } from 'nmtjs/runtime/types'
|
|
5
9
|
|
|
6
|
-
import type {
|
|
7
|
-
import type { JobWorkerPool, StoreType } from '../enums.ts'
|
|
10
|
+
import type { StoreType } from '../enums.ts'
|
|
8
11
|
import type { AnyJob } from '../jobs/job.ts'
|
|
9
12
|
import type { JobsSchedulerOptions } from '../scheduler/index.ts'
|
|
10
13
|
import type { SubscriptionAdapterType } from '../subscription/manager.ts'
|
|
@@ -26,25 +29,23 @@ export type ServerStoreConfig =
|
|
|
26
29
|
| { type: StoreType.Redis; options: StoreTypeOptions[StoreType.Redis] }
|
|
27
30
|
| { type: StoreType.Valkey; options: StoreTypeOptions[StoreType.Valkey] }
|
|
28
31
|
|
|
29
|
-
export type ServerApplicationConfig<T =
|
|
30
|
-
T extends
|
|
32
|
+
export type ServerApplicationConfig<T = ApplicationHostDefinition> =
|
|
33
|
+
T extends ApplicationHostDefinition<any, infer Transports>
|
|
31
34
|
? {
|
|
32
35
|
threads: {
|
|
33
|
-
[K in keyof Transports]: Transports[K]
|
|
34
|
-
any,
|
|
35
|
-
infer Options
|
|
36
|
-
>
|
|
37
|
-
? Options
|
|
38
|
-
: never
|
|
36
|
+
[K in keyof Transports]: TransportOptionsOf<Transports[K]>
|
|
39
37
|
}[]
|
|
40
38
|
}
|
|
41
|
-
:
|
|
39
|
+
: T extends ApplicationHost<infer Transports>
|
|
40
|
+
? {
|
|
41
|
+
threads: {
|
|
42
|
+
[K in keyof Transports]: TransportOptionsOf<Transports[K]>
|
|
43
|
+
}[]
|
|
44
|
+
}
|
|
45
|
+
: any
|
|
42
46
|
|
|
43
47
|
export type ServerJobsConfig = {
|
|
44
|
-
pools:
|
|
45
|
-
[JobWorkerPool.Io]: ServerPoolOptions
|
|
46
|
-
[JobWorkerPool.Compute]: ServerPoolOptions
|
|
47
|
-
}
|
|
48
|
+
pools: Record<string, ServerPoolOptions>
|
|
48
49
|
jobs?: AnyJob[]
|
|
49
50
|
/**
|
|
50
51
|
* @deprecated Scheduler is currently being refactored and is not available.
|
|
@@ -53,14 +54,19 @@ export type ServerJobsConfig = {
|
|
|
53
54
|
scheduler?: JobsSchedulerOptions
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
type ServerApplicationDefinitionConfig<T> = T extends {
|
|
58
|
+
type: 'neemata'
|
|
59
|
+
definition: infer Definition
|
|
60
|
+
}
|
|
61
|
+
? ServerApplicationConfig<Definition>
|
|
62
|
+
: ServerApplicationConfig<any>
|
|
63
|
+
|
|
56
64
|
export interface ServerConfigInit {
|
|
57
65
|
logger: LoggingOptions
|
|
58
66
|
applications: {
|
|
59
|
-
[K in keyof Applications]:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
>
|
|
63
|
-
: ServerApplicationConfig<any>
|
|
67
|
+
[K in keyof Applications]: ServerApplicationDefinitionConfig<
|
|
68
|
+
Applications[K]
|
|
69
|
+
>
|
|
64
70
|
}
|
|
65
71
|
store?: ServerStoreConfig
|
|
66
72
|
/**
|
|
@@ -14,10 +14,12 @@ import type {
|
|
|
14
14
|
WorkerPoolConfig,
|
|
15
15
|
WorkerPoolFactory,
|
|
16
16
|
} from './worker-pool.ts'
|
|
17
|
-
import {
|
|
17
|
+
import { WorkerType } from '../enums.ts'
|
|
18
18
|
import { getJobQueueName } from '../jobs/manager.ts'
|
|
19
19
|
import { JobRunnersPool } from './worker-pool.ts'
|
|
20
20
|
|
|
21
|
+
type JobsPoolConfig = Exclude<ServerConfig['jobs'], undefined>['pools']
|
|
22
|
+
|
|
21
23
|
function enrichBullMqErrorStack(error: unknown): Error {
|
|
22
24
|
const normalized =
|
|
23
25
|
error instanceof Error
|
|
@@ -31,6 +33,38 @@ function enrichBullMqErrorStack(error: unknown): Error {
|
|
|
31
33
|
return normalized
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
function getJobsByPool(jobs: Iterable<AnyJob>): Map<string, AnyJob[]> {
|
|
37
|
+
const jobsByPool = new Map<string, AnyJob[]>()
|
|
38
|
+
|
|
39
|
+
for (const job of jobs) {
|
|
40
|
+
const poolJobs = jobsByPool.get(job.options.pool)
|
|
41
|
+
if (poolJobs) {
|
|
42
|
+
poolJobs.push(job)
|
|
43
|
+
} else {
|
|
44
|
+
jobsByPool.set(job.options.pool, [job])
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return jobsByPool
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function assertActiveJobPoolsConfigured(
|
|
52
|
+
jobsByPool: Map<string, AnyJob[]>,
|
|
53
|
+
pools: JobsPoolConfig,
|
|
54
|
+
) {
|
|
55
|
+
const missingPoolMessages = [...jobsByPool]
|
|
56
|
+
.filter(([poolName]) => !pools[poolName])
|
|
57
|
+
.flatMap(([poolName, jobs]) =>
|
|
58
|
+
jobs.map((job) => `${job.name} -> ${poolName}`),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
if (missingPoolMessages.length > 0) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Invalid jobs pool configuration: missing pool config for jobs: ${missingPoolMessages.join(', ')}`,
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
34
68
|
/**
|
|
35
69
|
* ApplicationServerJobs manages job worker pools and BullMQ queue workers.
|
|
36
70
|
*
|
|
@@ -38,7 +72,7 @@ function enrichBullMqErrorStack(error: unknown): Error {
|
|
|
38
72
|
* - Uses JobRunnersPool (extends WorkerPool) for worker management
|
|
39
73
|
* - Uses ManagedWorker for restart logic and state tracking
|
|
40
74
|
* - Integrates with ErrorPolicy for restart decisions
|
|
41
|
-
* - Proper health tracking per job pool
|
|
75
|
+
* - Proper health tracking per job pool
|
|
42
76
|
*/
|
|
43
77
|
export class ApplicationServerJobs {
|
|
44
78
|
/**
|
|
@@ -49,10 +83,10 @@ export class ApplicationServerJobs {
|
|
|
49
83
|
jobs: Map<string, AnyJob>
|
|
50
84
|
|
|
51
85
|
/**
|
|
52
|
-
* Shared resource pools by pool
|
|
53
|
-
* All jobs
|
|
86
|
+
* Shared resource pools by configured pool name.
|
|
87
|
+
* All jobs using the same pool name share the same pool for resource management.
|
|
54
88
|
*/
|
|
55
|
-
protected pools = new Map<
|
|
89
|
+
protected pools = new Map<string, JobRunnersPool>()
|
|
56
90
|
|
|
57
91
|
constructor(
|
|
58
92
|
readonly params: {
|
|
@@ -86,16 +120,16 @@ export class ApplicationServerJobs {
|
|
|
86
120
|
return
|
|
87
121
|
}
|
|
88
122
|
|
|
89
|
-
|
|
90
|
-
|
|
123
|
+
const jobsByPool = getJobsByPool(this.jobs.values())
|
|
124
|
+
assertActiveJobPoolsConfigured(jobsByPool, jobsConfig.pools)
|
|
91
125
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
126
|
+
// Step 1: Initialize shared resource pools used by active jobs
|
|
127
|
+
for (const poolName of jobsByPool.keys()) {
|
|
128
|
+
const poolConfig = jobsConfig.pools[poolName]!
|
|
95
129
|
|
|
96
|
-
// Create a JobRunnersPool for this pool
|
|
130
|
+
// Create a JobRunnersPool for this pool
|
|
97
131
|
const config: WorkerPoolConfig = {
|
|
98
|
-
name: `job-pool-${
|
|
132
|
+
name: `job-pool-${poolName}`,
|
|
99
133
|
workerType: WorkerType.Job,
|
|
100
134
|
path: workerConfig.path,
|
|
101
135
|
workerData: { ...workerConfig.workerData },
|
|
@@ -111,15 +145,15 @@ export class ApplicationServerJobs {
|
|
|
111
145
|
|
|
112
146
|
// Add workers to the pool
|
|
113
147
|
for (let i = 0; i < poolConfig.threads; i++) {
|
|
114
|
-
pool.add({ runtime: { type: 'jobs', jobWorkerPool:
|
|
148
|
+
pool.add({ runtime: { type: 'jobs', jobWorkerPool: poolName } }, i)
|
|
115
149
|
}
|
|
116
150
|
|
|
117
151
|
await pool.startAll()
|
|
118
|
-
this.pools.set(
|
|
152
|
+
this.pools.set(poolName, pool)
|
|
119
153
|
|
|
120
154
|
logger.info(
|
|
121
155
|
{
|
|
122
|
-
pool:
|
|
156
|
+
pool: poolName,
|
|
123
157
|
threads: poolConfig.threads,
|
|
124
158
|
jobsPerThread: poolConfig.jobs,
|
|
125
159
|
},
|
|
@@ -129,28 +163,18 @@ export class ApplicationServerJobs {
|
|
|
129
163
|
|
|
130
164
|
// Step 2: Create a dedicated BullMQ Worker for each job
|
|
131
165
|
// Calculate how many jobs use each pool for fair concurrency distribution
|
|
132
|
-
const jobsPerPool = new Map<JobWorkerPool, number>()
|
|
133
|
-
for (const job of this.jobs.values()) {
|
|
134
|
-
const count = jobsPerPool.get(job.options.pool) ?? 0
|
|
135
|
-
jobsPerPool.set(job.options.pool, count + 1)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
166
|
for (const job of this.jobs.values()) {
|
|
139
167
|
const queueName = getJobQueueName(job)
|
|
140
|
-
const
|
|
141
|
-
const pool = this.pools.get(
|
|
168
|
+
const poolName = job.options.pool
|
|
169
|
+
const pool = this.pools.get(poolName)
|
|
142
170
|
|
|
143
171
|
if (!pool) {
|
|
144
|
-
|
|
145
|
-
{ job: job.name, pool: poolType },
|
|
146
|
-
'No pool configured for job, skipping worker creation',
|
|
147
|
-
)
|
|
148
|
-
continue
|
|
172
|
+
throw new Error(`Job "${job.name}" pool "${poolName}" is not started`)
|
|
149
173
|
}
|
|
150
174
|
|
|
151
|
-
const poolConfig = jobsConfig.pools[
|
|
175
|
+
const poolConfig = jobsConfig.pools[poolName]!
|
|
152
176
|
const poolCapacity = poolConfig.threads * poolConfig.jobs
|
|
153
|
-
const jobCountInPool =
|
|
177
|
+
const jobCountInPool = jobsByPool.get(poolName)?.length ?? 1
|
|
154
178
|
// Use job-specific concurrency if provided, otherwise distribute pool capacity evenly
|
|
155
179
|
const defaultConcurrency = Math.max(
|
|
156
180
|
1,
|
|
@@ -192,7 +216,7 @@ export class ApplicationServerJobs {
|
|
|
192
216
|
|
|
193
217
|
this.queueWorkers.add(queueWorker)
|
|
194
218
|
logger.info(
|
|
195
|
-
{ job: job.name, queue: queueName, pool:
|
|
219
|
+
{ job: job.name, queue: queueName, pool: poolName, concurrency },
|
|
196
220
|
'Job queue worker started',
|
|
197
221
|
)
|
|
198
222
|
}
|
|
@@ -234,9 +258,9 @@ export class ApplicationServerJobs {
|
|
|
234
258
|
}
|
|
235
259
|
|
|
236
260
|
/**
|
|
237
|
-
* Get a job pool by
|
|
261
|
+
* Get a job pool by name.
|
|
238
262
|
*/
|
|
239
|
-
getPool(
|
|
240
|
-
return this.pools.get(
|
|
263
|
+
getPool(poolName: string): JobRunnersPool | undefined {
|
|
264
|
+
return this.pools.get(poolName)
|
|
241
265
|
}
|
|
242
266
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import EventEmitter, { on } from 'node:events'
|
|
2
2
|
|
|
3
|
+
import type { RuntimePlugin } from '@nmtjs/application'
|
|
3
4
|
import type { Logger } from '@nmtjs/core'
|
|
4
5
|
import { isAbortError } from '@nmtjs/common'
|
|
5
6
|
import { createFactoryInjectable } from '@nmtjs/core'
|
|
6
7
|
|
|
7
|
-
import type { RuntimePlugin } from '../plugin.ts'
|
|
8
8
|
import type { Store } from '../types.ts'
|
|
9
9
|
import type {
|
|
10
10
|
SubscriptionAdapterEvent,
|
package/src/runtime/types.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ApplicationHostDefinition } from '@nmtjs/application'
|
|
2
2
|
import type { ProxyableTransportType } from '@nmtjs/gateway'
|
|
3
3
|
import type { Redis, RedisOptions } from 'ioredis'
|
|
4
4
|
import type { Redis as Valkey, RedisOptions as ValkeyOptions } from 'iovalkey'
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
import type { LifecycleHook, StoreType } from './enums.ts'
|
|
8
|
-
import type { BaseRuntime } from './runtime.ts'
|
|
6
|
+
import type { StoreType } from './enums.ts'
|
|
9
7
|
|
|
10
8
|
export type WorkerThreadErrorOrigin = 'bootstrap' | 'start' | 'runtime'
|
|
11
9
|
|
|
@@ -66,15 +64,8 @@ export type JobTaskResultTypes = {
|
|
|
66
64
|
queue_job_not_found: {}
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
export interface LifecycleHookTypes extends HookTypes {
|
|
70
|
-
[LifecycleHook.BeforeInitialize]: (runtime: BaseRuntime) => any
|
|
71
|
-
[LifecycleHook.AfterInitialize]: (runtime: BaseRuntime) => any
|
|
72
|
-
[LifecycleHook.BeforeDispose]: (runtime: BaseRuntime) => any
|
|
73
|
-
[LifecycleHook.AfterDispose]: (runtime: BaseRuntime) => any
|
|
74
|
-
}
|
|
75
|
-
|
|
76
67
|
export type ApplicationDefinitionType =
|
|
77
|
-
| { type: 'neemata'; definition:
|
|
68
|
+
| { type: 'neemata'; definition: ApplicationHostDefinition }
|
|
78
69
|
| { type: 'custom'; definition: any }
|
|
79
70
|
|
|
80
71
|
export interface Applications
|