nmtjs 0.16.1 → 0.17.0-beta.2
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/LICENSE.md +1 -1
- package/README.md +41 -1
- package/dist/index.d.ts +22 -161
- package/dist/index.js +24 -53
- package/dist/index.js.map +1 -1
- package/package.json +11 -63
- package/src/index.ts +71 -91
- package/bin/cli.js +0 -2
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -137
- package/dist/cli.js.map +0 -1
- package/dist/codegen.d.ts +0 -5
- package/dist/codegen.js +0 -18
- package/dist/codegen.js.map +0 -1
- package/dist/config.d.ts +0 -47
- package/dist/config.js +0 -16
- package/dist/config.js.map +0 -1
- package/dist/entrypoints/cli.d.ts +0 -1
- package/dist/entrypoints/cli.js +0 -12
- package/dist/entrypoints/cli.js.map +0 -1
- package/dist/entrypoints/main.d.ts +0 -5
- package/dist/entrypoints/main.js +0 -248
- package/dist/entrypoints/main.js.map +0 -1
- package/dist/entrypoints/thread.d.ts +0 -16
- package/dist/entrypoints/thread.js +0 -182
- package/dist/entrypoints/thread.js.map +0 -1
- package/dist/entrypoints/worker.d.ts +0 -9
- package/dist/entrypoints/worker.js +0 -143
- package/dist/entrypoints/worker.js.map +0 -1
- package/dist/resolver.d.ts +0 -2
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/runtime/application/index.d.ts +0 -1
- package/dist/runtime/application/index.js +0 -2
- package/dist/runtime/application/index.js.map +0 -1
- package/dist/runtime/constants.d.ts +0 -8
- package/dist/runtime/constants.js +0 -5
- package/dist/runtime/constants.js.map +0 -1
- package/dist/runtime/enums.d.ts +0 -10
- package/dist/runtime/enums.js +0 -13
- package/dist/runtime/enums.js.map +0 -1
- package/dist/runtime/hooks.d.ts +0 -1
- package/dist/runtime/hooks.js +0 -2
- package/dist/runtime/hooks.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -28
- package/dist/runtime/index.js +0 -29
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/injectables.d.ts +0 -69
- package/dist/runtime/injectables.js +0 -40
- package/dist/runtime/injectables.js.map +0 -1
- package/dist/runtime/jobs/job.d.ts +0 -146
- package/dist/runtime/jobs/job.js +0 -89
- package/dist/runtime/jobs/job.js.map +0 -1
- package/dist/runtime/jobs/manager.d.ts +0 -131
- package/dist/runtime/jobs/manager.js +0 -309
- package/dist/runtime/jobs/manager.js.map +0 -1
- package/dist/runtime/jobs/router.d.ts +0 -296
- package/dist/runtime/jobs/router.js +0 -458
- package/dist/runtime/jobs/router.js.map +0 -1
- package/dist/runtime/jobs/runner.d.ts +0 -103
- package/dist/runtime/jobs/runner.js +0 -425
- package/dist/runtime/jobs/runner.js.map +0 -1
- package/dist/runtime/jobs/step.d.ts +0 -26
- package/dist/runtime/jobs/step.js +0 -18
- package/dist/runtime/jobs/step.js.map +0 -1
- package/dist/runtime/jobs/types.d.ts +0 -86
- package/dist/runtime/jobs/types.js +0 -5
- package/dist/runtime/jobs/types.js.map +0 -1
- package/dist/runtime/metrics/metric.d.ts +0 -8
- package/dist/runtime/metrics/metric.js +0 -11
- package/dist/runtime/metrics/metric.js.map +0 -1
- package/dist/runtime/metrics/registry.d.ts +0 -3
- package/dist/runtime/metrics/registry.js +0 -5
- package/dist/runtime/metrics/registry.js.map +0 -1
- package/dist/runtime/metrics/server.d.ts +0 -7
- package/dist/runtime/metrics/server.js +0 -53
- package/dist/runtime/metrics/server.js.map +0 -1
- package/dist/runtime/plugin.d.ts +0 -2
- package/dist/runtime/plugin.js +0 -2
- package/dist/runtime/plugin.js.map +0 -1
- package/dist/runtime/runtime.d.ts +0 -27
- package/dist/runtime/runtime.js +0 -77
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/scheduler/index.d.ts +0 -22
- package/dist/runtime/scheduler/index.js +0 -20
- package/dist/runtime/scheduler/index.js.map +0 -1
- package/dist/runtime/server/applications.d.ts +0 -91
- package/dist/runtime/server/applications.js +0 -171
- package/dist/runtime/server/applications.js.map +0 -1
- package/dist/runtime/server/config.d.ts +0 -148
- package/dist/runtime/server/config.js +0 -33
- package/dist/runtime/server/config.js.map +0 -1
- package/dist/runtime/server/environment.d.ts +0 -43
- package/dist/runtime/server/environment.js +0 -33
- package/dist/runtime/server/environment.js.map +0 -1
- package/dist/runtime/server/error-policy.d.ts +0 -62
- package/dist/runtime/server/error-policy.js +0 -73
- package/dist/runtime/server/error-policy.js.map +0 -1
- package/dist/runtime/server/hmr-coordinator.d.ts +0 -37
- package/dist/runtime/server/hmr-coordinator.js +0 -94
- package/dist/runtime/server/hmr-coordinator.js.map +0 -1
- package/dist/runtime/server/jobs.d.ts +0 -54
- package/dist/runtime/server/jobs.js +0 -176
- package/dist/runtime/server/jobs.js.map +0 -1
- package/dist/runtime/server/lifecycle.d.ts +0 -85
- package/dist/runtime/server/lifecycle.js +0 -177
- package/dist/runtime/server/lifecycle.js.map +0 -1
- package/dist/runtime/server/managed-worker.d.ts +0 -158
- package/dist/runtime/server/managed-worker.js +0 -420
- package/dist/runtime/server/managed-worker.js.map +0 -1
- package/dist/runtime/server/pool-manager.d.ts +0 -85
- package/dist/runtime/server/pool-manager.js +0 -129
- package/dist/runtime/server/pool-manager.js.map +0 -1
- package/dist/runtime/server/proxy.d.ts +0 -21
- package/dist/runtime/server/proxy.js +0 -76
- package/dist/runtime/server/proxy.js.map +0 -1
- package/dist/runtime/server/server.d.ts +0 -60
- package/dist/runtime/server/server.js +0 -163
- package/dist/runtime/server/server.js.map +0 -1
- package/dist/runtime/server/types.d.ts +0 -31
- package/dist/runtime/server/types.js +0 -2
- package/dist/runtime/server/types.js.map +0 -1
- package/dist/runtime/server/worker-pool.d.ts +0 -121
- package/dist/runtime/server/worker-pool.js +0 -171
- package/dist/runtime/server/worker-pool.js.map +0 -1
- package/dist/runtime/store/index.d.ts +0 -3
- package/dist/runtime/store/index.js +0 -23
- package/dist/runtime/store/index.js.map +0 -1
- package/dist/runtime/subscription/manager.d.ts +0 -49
- package/dist/runtime/subscription/manager.js +0 -170
- package/dist/runtime/subscription/manager.js.map +0 -1
- package/dist/runtime/subscription/redis.d.ts +0 -18
- package/dist/runtime/subscription/redis.js +0 -119
- package/dist/runtime/subscription/redis.js.map +0 -1
- package/dist/runtime/types.d.ts +0 -95
- package/dist/runtime/types.js +0 -2
- package/dist/runtime/types.js.map +0 -1
- package/dist/runtime/workers/application.d.ts +0 -29
- package/dist/runtime/workers/application.js +0 -77
- package/dist/runtime/workers/application.js.map +0 -1
- package/dist/runtime/workers/base.d.ts +0 -14
- package/dist/runtime/workers/base.js +0 -41
- package/dist/runtime/workers/base.js.map +0 -1
- package/dist/runtime/workers/cli.d.ts +0 -1
- package/dist/runtime/workers/cli.js +0 -2
- package/dist/runtime/workers/cli.js.map +0 -1
- package/dist/runtime/workers/job.d.ts +0 -20
- package/dist/runtime/workers/job.js +0 -170
- package/dist/runtime/workers/job.js.map +0 -1
- package/dist/vite/builder.d.ts +0 -5
- package/dist/vite/builder.js +0 -79
- package/dist/vite/builder.js.map +0 -1
- package/dist/vite/config.d.ts +0 -28
- package/dist/vite/config.js +0 -22
- package/dist/vite/config.js.map +0 -1
- package/dist/vite/plugins.d.ts +0 -2
- package/dist/vite/plugins.js +0 -43
- package/dist/vite/plugins.js.map +0 -1
- package/dist/vite/runners/worker.d.ts +0 -3
- package/dist/vite/runners/worker.js +0 -34
- package/dist/vite/runners/worker.js.map +0 -1
- package/dist/vite/server.d.ts +0 -3
- package/dist/vite/server.js +0 -36
- package/dist/vite/server.js.map +0 -1
- package/dist/vite/servers/main.d.ts +0 -8
- package/dist/vite/servers/main.js +0 -24
- package/dist/vite/servers/main.js.map +0 -1
- package/dist/vite/servers/worker.d.ts +0 -13
- package/dist/vite/servers/worker.js +0 -124
- package/dist/vite/servers/worker.js.map +0 -1
- package/src/cli.ts +0 -162
- package/src/codegen.ts +0 -30
- package/src/config.ts +0 -69
- package/src/entrypoints/cli.ts +0 -13
- package/src/entrypoints/main.ts +0 -317
- package/src/entrypoints/thread.ts +0 -223
- package/src/entrypoints/worker.ts +0 -174
- package/src/resolver.ts +0 -7
- package/src/runtime/application/index.ts +0 -1
- package/src/runtime/constants.ts +0 -13
- package/src/runtime/enums.ts +0 -12
- package/src/runtime/hooks.ts +0 -1
- package/src/runtime/index.ts +0 -29
- package/src/runtime/injectables.ts +0 -101
- package/src/runtime/jobs/job.ts +0 -467
- package/src/runtime/jobs/manager.ts +0 -454
- package/src/runtime/jobs/router.ts +0 -967
- package/src/runtime/jobs/runner.ts +0 -583
- package/src/runtime/jobs/step.ts +0 -66
- package/src/runtime/jobs/types.ts +0 -116
- package/src/runtime/metrics/metric.ts +0 -18
- package/src/runtime/metrics/registry.ts +0 -11
- package/src/runtime/metrics/server.ts +0 -69
- package/src/runtime/plugin.ts +0 -2
- package/src/runtime/runtime.ts +0 -103
- package/src/runtime/scheduler/index.ts +0 -39
- package/src/runtime/server/applications.ts +0 -264
- package/src/runtime/server/config.ts +0 -199
- package/src/runtime/server/environment.ts +0 -71
- package/src/runtime/server/error-policy.ts +0 -132
- package/src/runtime/server/hmr-coordinator.ts +0 -116
- package/src/runtime/server/jobs.ts +0 -266
- package/src/runtime/server/lifecycle.ts +0 -234
- package/src/runtime/server/managed-worker.ts +0 -546
- package/src/runtime/server/pool-manager.ts +0 -187
- package/src/runtime/server/proxy.ts +0 -119
- package/src/runtime/server/server.ts +0 -218
- package/src/runtime/server/types.ts +0 -32
- package/src/runtime/server/worker-pool.ts +0 -275
- package/src/runtime/store/index.ts +0 -30
- package/src/runtime/subscription/manager.ts +0 -307
- package/src/runtime/subscription/redis.ts +0 -159
- package/src/runtime/types.ts +0 -84
- package/src/runtime/workers/application.ts +0 -133
- package/src/runtime/workers/base.ts +0 -65
- package/src/runtime/workers/cli.ts +0 -0
- package/src/runtime/workers/job.ts +0 -142
- package/src/vite/builder.ts +0 -94
- package/src/vite/config.ts +0 -45
- package/src/vite/plugins.ts +0 -53
- package/src/vite/runners/worker.ts +0 -55
- package/src/vite/server.ts +0 -55
- package/src/vite/servers/main.ts +0 -41
- package/src/vite/servers/worker.ts +0 -177
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// Job Definition Types (metadata about job structure)
|
|
3
|
-
// ============================================================================
|
|
4
|
-
|
|
5
|
-
/** Metadata about a job step in a job definition */
|
|
6
|
-
export interface JobStepInfo {
|
|
7
|
-
/** Optional human-readable label for the step */
|
|
8
|
-
label?: string
|
|
9
|
-
/** Whether this step has a condition that may skip it */
|
|
10
|
-
conditional: boolean
|
|
11
|
-
/** Whether this step executes in a parallel group */
|
|
12
|
-
parallel: boolean
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** Metadata about a job definition (not a running job instance) */
|
|
16
|
-
export interface JobDefinitionInfo {
|
|
17
|
-
/** Job name from definition */
|
|
18
|
-
name: string
|
|
19
|
-
/** Information about each step in the job */
|
|
20
|
-
steps: JobStepInfo[]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// ============================================================================
|
|
24
|
-
// Job Execution Types (runtime state of a running job)
|
|
25
|
-
// ============================================================================
|
|
26
|
-
|
|
27
|
-
/** Result of a single step execution */
|
|
28
|
-
export interface StepResultEntry {
|
|
29
|
-
/** Output data produced by the step, or null if skipped */
|
|
30
|
-
data: Record<string, unknown> | null
|
|
31
|
-
/** Timestamp when step started (ms since epoch) */
|
|
32
|
-
startedAt: number
|
|
33
|
-
/** Timestamp when step completed (ms since epoch) */
|
|
34
|
-
completedAt: number
|
|
35
|
-
/** Duration in milliseconds (completedAt - startedAt) */
|
|
36
|
-
duration: number
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** Checkpoint data persisted for job resume support */
|
|
40
|
-
export interface JobProgressCheckpoint {
|
|
41
|
-
/** Index of the next step to execute (0 = not started, length = completed) */
|
|
42
|
-
stepIndex: number
|
|
43
|
-
/** Label of the next step to execute, if labeled */
|
|
44
|
-
stepLabel?: string
|
|
45
|
-
/** Accumulated result from all completed steps */
|
|
46
|
-
result: Record<string, unknown>
|
|
47
|
-
/** Results of each individual step */
|
|
48
|
-
stepResults: StepResultEntry[]
|
|
49
|
-
/** User-defined progress state */
|
|
50
|
-
progress: Record<string, unknown>
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Information about the currently executing job, available via injectable */
|
|
54
|
-
export interface JobExecutionContext {
|
|
55
|
-
/** Job definition name */
|
|
56
|
-
name: string
|
|
57
|
-
/** Queue job ID */
|
|
58
|
-
id?: string
|
|
59
|
-
/** Queue name */
|
|
60
|
-
queue?: string
|
|
61
|
-
/** Number of attempts made so far */
|
|
62
|
-
attempts?: number
|
|
63
|
-
/** Current step index being executed */
|
|
64
|
-
stepIndex?: number
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ============================================================================
|
|
68
|
-
// Job Item Types (job instances from queue)
|
|
69
|
-
// ============================================================================
|
|
70
|
-
|
|
71
|
-
/** Vendor-agnostic job status */
|
|
72
|
-
export type JobStatus =
|
|
73
|
-
| 'pending' // Queued, waiting to be picked up
|
|
74
|
-
| 'active' // Currently executing
|
|
75
|
-
| 'completed' // Successfully finished
|
|
76
|
-
| 'failed' // Failed (may retry)
|
|
77
|
-
| 'delayed' // Scheduled for future
|
|
78
|
-
| 'cancelled' // Manually cancelled
|
|
79
|
-
| 'unknown' // State cannot be determined
|
|
80
|
-
|
|
81
|
-
/** A job instance retrieved from the queue */
|
|
82
|
-
export interface JobItem<TInput = unknown, TOutput = unknown> {
|
|
83
|
-
/** Unique job instance ID */
|
|
84
|
-
id: string
|
|
85
|
-
/** Job definition name */
|
|
86
|
-
name: string
|
|
87
|
-
/** Queue name this job belongs to */
|
|
88
|
-
queue: string
|
|
89
|
-
/** Input data passed to the job */
|
|
90
|
-
data: TInput
|
|
91
|
-
/** Output produced by the job (if completed) */
|
|
92
|
-
output?: TOutput | null
|
|
93
|
-
/** Current job status */
|
|
94
|
-
status: JobStatus
|
|
95
|
-
/** Job priority (lower = higher priority) */
|
|
96
|
-
priority?: number
|
|
97
|
-
/** Job progress checkpoint (includes step state and user progress) */
|
|
98
|
-
progress?: JobProgressCheckpoint
|
|
99
|
-
/** Number of execution attempts */
|
|
100
|
-
attempts: number
|
|
101
|
-
/** Timestamp when job started processing (ms) */
|
|
102
|
-
startedAt?: number
|
|
103
|
-
/** Timestamp when job completed (ms) */
|
|
104
|
-
completedAt?: number
|
|
105
|
-
/** Error message if job failed */
|
|
106
|
-
error?: string
|
|
107
|
-
/** Stack trace if job failed */
|
|
108
|
-
stacktrace: string[] | null
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ============================================================================
|
|
112
|
-
// Injectable Types
|
|
113
|
-
// ============================================================================
|
|
114
|
-
|
|
115
|
-
/** Function to manually trigger saving job progress state */
|
|
116
|
-
export type SaveJobProgress = () => Promise<void>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ClassConstructorArgs } from '@nmtjs/common'
|
|
2
|
-
import type { Metric, MetricConfiguration } from '@nmtjs/prom-client'
|
|
3
|
-
import { Counter, Gauge, Histogram, Summary } from '@nmtjs/prom-client'
|
|
4
|
-
|
|
5
|
-
import { registry } from './registry.ts'
|
|
6
|
-
|
|
7
|
-
export const createMetric =
|
|
8
|
-
<T extends Metric>(contructor: new (config: MetricConfiguration<any>) => T) =>
|
|
9
|
-
(config: ClassConstructorArgs<T>[0]): T =>
|
|
10
|
-
new contructor({
|
|
11
|
-
...config,
|
|
12
|
-
registers: [...(config.registers ?? []), registry],
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
export const createCounterMetric = createMetric(Counter)
|
|
16
|
-
export const createGaugeMetric = createMetric(Gauge)
|
|
17
|
-
export const createHistogramMetric = createMetric(Histogram)
|
|
18
|
-
export const createSummaryMetric = createMetric(Summary)
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { createServer } from 'node:http'
|
|
2
|
-
|
|
3
|
-
import type { Logger } from '@nmtjs/core'
|
|
4
|
-
import { Pushgateway } from '@nmtjs/prom-client'
|
|
5
|
-
|
|
6
|
-
import type { ServerConfig } from '../server/config.ts'
|
|
7
|
-
|
|
8
|
-
export async function createMetricsServer(
|
|
9
|
-
logger: Logger,
|
|
10
|
-
config: Exclude<ServerConfig['metrics'], undefined>,
|
|
11
|
-
) {
|
|
12
|
-
const { workerRegistry: registry } = await import('./registry.ts')
|
|
13
|
-
const { host = '0.0.0.0', port = 9187, path = '/metrics', push } = config
|
|
14
|
-
|
|
15
|
-
let intervalRef: any
|
|
16
|
-
|
|
17
|
-
if (push) {
|
|
18
|
-
const { url = 'http://127.0.0.1:9091', interval, name: jobName } = push
|
|
19
|
-
const gateway = new Pushgateway(url, {}, registry)
|
|
20
|
-
intervalRef = setInterval(() => {
|
|
21
|
-
gateway
|
|
22
|
-
.pushAdd({ jobName })
|
|
23
|
-
.catch((cause) =>
|
|
24
|
-
logger.error(new Error('Metrics push error', { cause })),
|
|
25
|
-
)
|
|
26
|
-
}, interval)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const server = createServer((req, res) => {
|
|
30
|
-
const url = new URL(`http://${req.headers.host || 'localhost'}${req.url}`)
|
|
31
|
-
if (url.pathname === path) {
|
|
32
|
-
res.setHeader('Content-Type', registry.contentType)
|
|
33
|
-
registry
|
|
34
|
-
.workerMetrics()
|
|
35
|
-
.then((metrics) => {
|
|
36
|
-
res.writeHead(200)
|
|
37
|
-
res.end(metrics)
|
|
38
|
-
})
|
|
39
|
-
.catch((cause) => {
|
|
40
|
-
logger.error(new Error('Metrics collection error', { cause }))
|
|
41
|
-
res.writeHead(500)
|
|
42
|
-
res.end('Internal Server Error')
|
|
43
|
-
})
|
|
44
|
-
} else {
|
|
45
|
-
res.writeHead(404)
|
|
46
|
-
res.end('Not Found')
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
start: () =>
|
|
52
|
-
new Promise<void>((resolve) =>
|
|
53
|
-
server.listen({ host: host, port: port }, resolve),
|
|
54
|
-
),
|
|
55
|
-
stop: () =>
|
|
56
|
-
new Promise<void>((resolve, reject) => {
|
|
57
|
-
if (intervalRef) clearInterval(intervalRef)
|
|
58
|
-
server.close((err) => {
|
|
59
|
-
if (err) {
|
|
60
|
-
reject(err)
|
|
61
|
-
} else {
|
|
62
|
-
resolve()
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
}),
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export type MetricsServer = Awaited<ReturnType<typeof createMetricsServer>>
|
package/src/runtime/plugin.ts
DELETED
package/src/runtime/runtime.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import type { RuntimePlugin } from '@nmtjs/application'
|
|
2
|
-
import type {
|
|
3
|
-
AnyInjectable,
|
|
4
|
-
Dependant,
|
|
5
|
-
Logger,
|
|
6
|
-
LoggingOptions,
|
|
7
|
-
} from '@nmtjs/core'
|
|
8
|
-
import { LifecycleHook, LifecycleHooks } from '@nmtjs/application'
|
|
9
|
-
import {
|
|
10
|
-
Container,
|
|
11
|
-
createLogger,
|
|
12
|
-
getDepedencencyInjectable,
|
|
13
|
-
Scope,
|
|
14
|
-
} from '@nmtjs/core'
|
|
15
|
-
|
|
16
|
-
export type BaseRuntimeOptions = {
|
|
17
|
-
logger?: LoggingOptions
|
|
18
|
-
container?: Container
|
|
19
|
-
plugins?: RuntimePlugin[]
|
|
20
|
-
name?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export abstract class BaseRuntime {
|
|
24
|
-
logger: Logger
|
|
25
|
-
container: Container
|
|
26
|
-
lifecycleHooks: LifecycleHooks
|
|
27
|
-
plugins: RuntimePlugin[]
|
|
28
|
-
|
|
29
|
-
constructor(options: BaseRuntimeOptions = {}) {
|
|
30
|
-
this.logger = createLogger(options.logger, options.name || 'Runtime')
|
|
31
|
-
this.container = options.container
|
|
32
|
-
? options.container.fork(Scope.Global)
|
|
33
|
-
: new Container({ logger: this.logger })
|
|
34
|
-
this.lifecycleHooks = new LifecycleHooks()
|
|
35
|
-
this.plugins = options.plugins || []
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
protected abstract _initialize(): Promise<void>
|
|
39
|
-
protected abstract _dispose(): Promise<void>
|
|
40
|
-
protected abstract _dependents(): Generator<Dependant>
|
|
41
|
-
|
|
42
|
-
async reload(...args: any[]): Promise<void> {
|
|
43
|
-
await this._dispose()
|
|
44
|
-
await this._initialize()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async initialize() {
|
|
48
|
-
this.logger.debug('Initializing a runtime...')
|
|
49
|
-
await this._initializePlugins()
|
|
50
|
-
await this._initializeContainer()
|
|
51
|
-
await this.lifecycleHooks.callHook(LifecycleHook.BeforeInitialize, this)
|
|
52
|
-
await this._initialize()
|
|
53
|
-
await this.lifecycleHooks.callHook(LifecycleHook.AfterInitialize, this)
|
|
54
|
-
this.logger.debug('Runtime initialized')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async dispose() {
|
|
58
|
-
this.logger.debug('Disposing a runtime...')
|
|
59
|
-
await this.lifecycleHooks.callHook(LifecycleHook.BeforeDispose, this)
|
|
60
|
-
await this._dispose()
|
|
61
|
-
await this.lifecycleHooks.callHook(LifecycleHook.AfterDispose, this)
|
|
62
|
-
await this._disposeContainer()
|
|
63
|
-
await this._disposePlugins()
|
|
64
|
-
this.logger.debug('Runtime disposed')
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
protected async _initializePlugins() {
|
|
68
|
-
if (!this.plugins?.length) return
|
|
69
|
-
for (const { name, hooks, injections } of this.plugins) {
|
|
70
|
-
this.logger.debug(`Initializing plugin [${name}]...`)
|
|
71
|
-
if (injections) this.container.provide(injections)
|
|
72
|
-
if (hooks) this.lifecycleHooks.addHooks(hooks)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
protected async _disposePlugins() {
|
|
77
|
-
if (!this.plugins?.length) return
|
|
78
|
-
for (const { name, hooks, injections } of this.plugins) {
|
|
79
|
-
this.logger.debug(`Disposing plugin [${name}]...`)
|
|
80
|
-
if (hooks) this.lifecycleHooks.removeHooks(hooks)
|
|
81
|
-
if (injections) {
|
|
82
|
-
for (const injection of injections) {
|
|
83
|
-
await this.container.disposeInjectableInstances(injection.token)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
protected async _initializeContainer() {
|
|
90
|
-
const dependents = this._dependents()
|
|
91
|
-
const dependencies = new Set<AnyInjectable>()
|
|
92
|
-
for (const dependant of dependents) {
|
|
93
|
-
for (const dependency of Object.values(dependant.dependencies)) {
|
|
94
|
-
dependencies.add(getDepedencencyInjectable(dependency))
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
await this.container.initialize(dependencies)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
protected async _disposeContainer() {
|
|
101
|
-
await this.container.dispose()
|
|
102
|
-
}
|
|
103
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { AnyJob } from '../jobs/job.ts'
|
|
2
|
-
|
|
3
|
-
export interface JobsSchedulerEntry<T extends AnyJob = AnyJob> {
|
|
4
|
-
job: T
|
|
5
|
-
data: T['_']['input']
|
|
6
|
-
cron: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type JobsSchedulerOptions = { entries: JobsSchedulerEntry[] }
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @deprecated Job scheduler is currently being refactored and is not available.
|
|
13
|
-
* This will throw an error if instantiated.
|
|
14
|
-
*/
|
|
15
|
-
export class JobsScheduler {
|
|
16
|
-
constructor() {
|
|
17
|
-
throw new Error(
|
|
18
|
-
'JobsScheduler is currently a work in progress and not available. ' +
|
|
19
|
-
'Scheduled jobs will be supported in a future release.',
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async initialize() {}
|
|
24
|
-
async stop() {}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @deprecated Job scheduler is currently being refactored and is not available.
|
|
29
|
-
*/
|
|
30
|
-
export function createSchedulerJobEntry<T extends AnyJob>(
|
|
31
|
-
job: T,
|
|
32
|
-
data: T['_']['input'],
|
|
33
|
-
cron: string,
|
|
34
|
-
): JobsSchedulerEntry<T> {
|
|
35
|
-
throw new Error(
|
|
36
|
-
'createSchedulerJobEntry is currently a work in progress and not available. ' +
|
|
37
|
-
'Scheduled jobs will be supported in a future release.',
|
|
38
|
-
)
|
|
39
|
-
}
|
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import EventEmitter from 'node:events'
|
|
2
|
-
|
|
3
|
-
import type { Logger } from '@nmtjs/core'
|
|
4
|
-
import type { ProxyableTransportType } from '@nmtjs/gateway'
|
|
5
|
-
|
|
6
|
-
import type { ThreadPortMessageTypes, WorkerThreadError } from '../types.ts'
|
|
7
|
-
import type { ServerApplicationConfig, ServerConfig } from './config.ts'
|
|
8
|
-
import type { ErrorPolicy } from './error-policy.ts'
|
|
9
|
-
import type { ManagedWorker } from './managed-worker.ts'
|
|
10
|
-
import type { ApplicationServerWorkerConfig } from './types.ts'
|
|
11
|
-
import type {
|
|
12
|
-
ManagedWorkerFactory,
|
|
13
|
-
WorkerPool,
|
|
14
|
-
WorkerPoolConfig,
|
|
15
|
-
WorkerPoolFactory,
|
|
16
|
-
} from './worker-pool.ts'
|
|
17
|
-
import { WorkerType } from '../enums.ts'
|
|
18
|
-
|
|
19
|
-
export type ApplicationProxyUpstream = {
|
|
20
|
-
type: ProxyableTransportType
|
|
21
|
-
url: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* ApplicationServerApplications manages all application worker pools.
|
|
26
|
-
*
|
|
27
|
-
* Changes from the old Pool-based implementation:
|
|
28
|
-
* - Uses WorkerPool for each application (isolated failure domains)
|
|
29
|
-
* - Uses ManagedWorker for restart logic and state tracking
|
|
30
|
-
* - Integrates with ErrorPolicy for restart decisions
|
|
31
|
-
* - Proper health tracking per application
|
|
32
|
-
*/
|
|
33
|
-
export class ApplicationServerApplications extends EventEmitter<{
|
|
34
|
-
add: [application: string, upstream: ApplicationProxyUpstream]
|
|
35
|
-
remove: [application: string, upstream: ApplicationProxyUpstream]
|
|
36
|
-
}> {
|
|
37
|
-
/** Worker pools per application */
|
|
38
|
-
private pools = new Map<string, WorkerPool>()
|
|
39
|
-
|
|
40
|
-
/** Upstreams for proxy routing */
|
|
41
|
-
protected readonly upstreams = new Map<
|
|
42
|
-
string,
|
|
43
|
-
Map<string, { upstream: ApplicationProxyUpstream; count: number }>
|
|
44
|
-
>()
|
|
45
|
-
|
|
46
|
-
/** Track upstreams by worker for cleanup */
|
|
47
|
-
protected readonly upstreamsByWorker = new WeakMap<
|
|
48
|
-
ManagedWorker,
|
|
49
|
-
Array<{ application: string; key: string }>
|
|
50
|
-
>()
|
|
51
|
-
|
|
52
|
-
constructor(
|
|
53
|
-
readonly params: {
|
|
54
|
-
logger: Logger
|
|
55
|
-
applications: string[]
|
|
56
|
-
workerConfig: ApplicationServerWorkerConfig
|
|
57
|
-
applicationsConfig: Record<
|
|
58
|
-
string,
|
|
59
|
-
{ type: 'neemata' | 'custom'; specifier: string }
|
|
60
|
-
>
|
|
61
|
-
serverConfig: ServerConfig
|
|
62
|
-
errorPolicy: ErrorPolicy
|
|
63
|
-
workerFactory: ManagedWorkerFactory
|
|
64
|
-
poolFactory: WorkerPoolFactory
|
|
65
|
-
},
|
|
66
|
-
) {
|
|
67
|
-
super()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get appsNames() {
|
|
71
|
-
return this.params.applications
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Start all application workers.
|
|
76
|
-
*/
|
|
77
|
-
async start() {
|
|
78
|
-
const {
|
|
79
|
-
logger,
|
|
80
|
-
applications,
|
|
81
|
-
applicationsConfig,
|
|
82
|
-
serverConfig,
|
|
83
|
-
workerConfig,
|
|
84
|
-
errorPolicy,
|
|
85
|
-
workerFactory,
|
|
86
|
-
poolFactory,
|
|
87
|
-
} = this.params
|
|
88
|
-
|
|
89
|
-
for (const applicationName of applications) {
|
|
90
|
-
const applicationPath = applicationsConfig[applicationName]
|
|
91
|
-
if (!applicationPath) {
|
|
92
|
-
logger.warn(
|
|
93
|
-
`Application [${applicationName}] not found in applicationsConfig, skipping...`,
|
|
94
|
-
)
|
|
95
|
-
continue
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const applicationConfig = serverConfig.applications[
|
|
99
|
-
applicationName
|
|
100
|
-
] as ServerApplicationConfig
|
|
101
|
-
|
|
102
|
-
const threadsConfig = Array.isArray(applicationConfig.threads)
|
|
103
|
-
? applicationConfig.threads
|
|
104
|
-
: new Array(applicationConfig.threads).fill(undefined)
|
|
105
|
-
|
|
106
|
-
logger.debug(
|
|
107
|
-
`Spinning [${threadsConfig.length}] workers for [${applicationName}] application...`,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
// Create a WorkerPool for this application
|
|
111
|
-
const poolConfig: WorkerPoolConfig = {
|
|
112
|
-
name: `application-${applicationName}`,
|
|
113
|
-
workerType: WorkerType.Application,
|
|
114
|
-
path: workerConfig.path,
|
|
115
|
-
workerData: { ...workerConfig.workerData },
|
|
116
|
-
onWorker: workerConfig.worker,
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const pool = poolFactory(poolConfig, errorPolicy, workerFactory, logger)
|
|
120
|
-
|
|
121
|
-
// Add workers to the pool
|
|
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
|
-
|
|
129
|
-
const workerData = {
|
|
130
|
-
runtime: {
|
|
131
|
-
type: 'application',
|
|
132
|
-
name: applicationName,
|
|
133
|
-
path: applicationPath.specifier,
|
|
134
|
-
transportsData: threadsConfig[i],
|
|
135
|
-
},
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const worker = pool.add(workerData, i)
|
|
139
|
-
|
|
140
|
-
// Handle worker ready - update upstreams
|
|
141
|
-
worker.on('ready', (hosts) => {
|
|
142
|
-
this.removeWorkerUpstreams(worker)
|
|
143
|
-
|
|
144
|
-
const keys: Array<{ application: string; key: string }> = []
|
|
145
|
-
const sanitizedHosts: ThreadPortMessageTypes['ready']['hosts'] = []
|
|
146
|
-
|
|
147
|
-
if (hosts?.length) {
|
|
148
|
-
for (const host of hosts) {
|
|
149
|
-
const url = new URL(host.url)
|
|
150
|
-
if (url.hostname === '0.0.0.0') url.hostname = '127.0.0.1'
|
|
151
|
-
|
|
152
|
-
const normalizedUrl = url.toString()
|
|
153
|
-
sanitizedHosts.push({ type: host.type, url: normalizedUrl })
|
|
154
|
-
|
|
155
|
-
const upstream: ApplicationProxyUpstream = {
|
|
156
|
-
type: host.type,
|
|
157
|
-
url: normalizedUrl,
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const key = `${upstream.type}:${upstream.url}`
|
|
161
|
-
keys.push({ application: applicationName, key })
|
|
162
|
-
this.addUpstream(applicationName, key, upstream)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
this.upstreamsByWorker.set(worker, keys)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
// Handle worker error - clean up upstreams
|
|
170
|
-
worker.on('error', (_error: WorkerThreadError) => {
|
|
171
|
-
this.removeWorkerUpstreams(worker)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
// Handle worker state changes for upstream cleanup
|
|
175
|
-
worker.on('state-change', (from, to) => {
|
|
176
|
-
if (to === 'stopping' || to === 'stopped' || to === 'error') {
|
|
177
|
-
this.removeWorkerUpstreams(worker)
|
|
178
|
-
}
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
this.pools.set(applicationName, pool)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Start all pools
|
|
186
|
-
await Promise.all([...this.pools.values()].map((p) => p.startAll()))
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Stop all application workers.
|
|
191
|
-
*/
|
|
192
|
-
async stop() {
|
|
193
|
-
await Promise.all([...this.pools.values()].map((p) => p.stopAll()))
|
|
194
|
-
this.pools.clear()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Restart failed workers across all pools.
|
|
199
|
-
* Called when HMR update comes in and workers may have failed.
|
|
200
|
-
* @returns Number of workers that were restarted
|
|
201
|
-
*/
|
|
202
|
-
async restartFailedWorkers(): Promise<number> {
|
|
203
|
-
let total = 0
|
|
204
|
-
for (const pool of this.pools.values()) {
|
|
205
|
-
total += await pool.restartFailedWorkers()
|
|
206
|
-
}
|
|
207
|
-
return total
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Get pool for an application.
|
|
212
|
-
*/
|
|
213
|
-
getPool(applicationName: string): WorkerPool | undefined {
|
|
214
|
-
return this.pools.get(applicationName)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Add an upstream for proxy routing.
|
|
219
|
-
*/
|
|
220
|
-
protected addUpstream(
|
|
221
|
-
application: string,
|
|
222
|
-
key: string,
|
|
223
|
-
upstream: ApplicationProxyUpstream,
|
|
224
|
-
) {
|
|
225
|
-
let appUpstreams = this.upstreams.get(application)
|
|
226
|
-
if (!appUpstreams) {
|
|
227
|
-
appUpstreams = new Map()
|
|
228
|
-
this.upstreams.set(application, appUpstreams)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const current = appUpstreams.get(key)
|
|
232
|
-
if (!current) {
|
|
233
|
-
appUpstreams.set(key, { upstream, count: 1 })
|
|
234
|
-
this.emit('add', application, upstream)
|
|
235
|
-
return
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
current.count++
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Remove upstreams associated with a worker.
|
|
243
|
-
*/
|
|
244
|
-
protected removeWorkerUpstreams(worker: ManagedWorker) {
|
|
245
|
-
const keys = this.upstreamsByWorker.get(worker)
|
|
246
|
-
if (!keys) return
|
|
247
|
-
this.upstreamsByWorker.delete(worker)
|
|
248
|
-
|
|
249
|
-
for (const { application, key } of keys) {
|
|
250
|
-
const appUpstreams = this.upstreams.get(application)
|
|
251
|
-
const current = appUpstreams?.get(key)
|
|
252
|
-
if (!current) continue
|
|
253
|
-
|
|
254
|
-
current.count--
|
|
255
|
-
if (current.count <= 0) {
|
|
256
|
-
appUpstreams?.delete(key)
|
|
257
|
-
this.emit('remove', application, current.upstream)
|
|
258
|
-
}
|
|
259
|
-
if (appUpstreams && appUpstreams.size === 0) {
|
|
260
|
-
this.upstreams.delete(application)
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|