Skip to content

Commit 7860a5c

Browse files
committed
feat(worker): add worker app type
1 parent e4432ee commit 7860a5c

11 files changed

Lines changed: 1823 additions & 140 deletions

File tree

package-lock.json

Lines changed: 1525 additions & 137 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@athenna/core",
3-
"version": "5.25.0",
3+
"version": "5.26.0",
44
"description": "One foundation for multiple applications.",
55
"license": "MIT",
66
"author": "João Lenon <lenon@athenna.io>",
@@ -88,6 +88,7 @@
8888
"@athenna/http": "^5.38.0",
8989
"@athenna/ioc": "^5.2.0",
9090
"@athenna/logger": "^5.8.0",
91+
"@athenna/queue": "^5.11.0",
9192
"@athenna/test": "^5.5.0",
9293
"@athenna/tsconfig": "^5.0.0",
9394
"@athenna/view": "^5.4.0",
@@ -227,6 +228,9 @@
227228
"directories": {
228229
"bootstrap": "bin"
229230
},
231+
"workers": [
232+
"#tests/fixtures/workers/HelloWorker"
233+
],
230234
"schedulers": [
231235
"#tests/fixtures/schedulers/HelloScheduler"
232236
],

src/applications/Worker.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @athenna/core
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { debug } from '#src/debug'
11+
import { Log } from '@athenna/logger'
12+
import type { WorkerImpl } from '@athenna/queue'
13+
import { Path, Module, Options } from '@athenna/common'
14+
import type { CronOptions } from '#src/types/CronOptions'
15+
16+
export class Worker {
17+
/**
18+
* Boot the Worker application.
19+
*/
20+
public static async boot(options?: CronOptions): Promise<WorkerImpl> {
21+
options = Options.create(options, {
22+
routePath: Config.get(
23+
'rc.worker.route',
24+
Path.routes(`worker.${Path.ext()}`)
25+
),
26+
kernelPath: Config.get(
27+
'rc.worker.kernel',
28+
'@athenna/queue/kernels/WorkerKernel'
29+
)
30+
})
31+
32+
const worker = ioc.safeUse('Athenna/Core/Worker')
33+
34+
debug('booting worker application with options %o', options)
35+
36+
await this.resolveKernel(options)
37+
38+
if (Config.notExists('rc.bootLogs') || Config.is('rc.bootLogs', false)) {
39+
return worker
40+
}
41+
42+
Log.channelOrVanilla('application').success(
43+
`Worker application successfully started`
44+
)
45+
46+
return worker
47+
}
48+
49+
/**
50+
* Resolve the kernel by importing it and calling the methods to register
51+
* worker tasks and plugins.
52+
*/
53+
private static async resolveKernel(options?: CronOptions) {
54+
const Kernel = await Module.resolve(
55+
options.kernelPath,
56+
Config.get('rc.parentURL')
57+
)
58+
59+
const kernel = new Kernel()
60+
61+
await kernel.registerLogger()
62+
await kernel.registerRTracer()
63+
await kernel.registerWorkers()
64+
await kernel.registerRoutes(options.routePath)
65+
66+
if (Config.is('rc.bootLogs', true)) {
67+
Log.channelOrVanilla('application').success(
68+
`Kernel ({yellow} ${Kernel.name}) successfully booted`
69+
)
70+
}
71+
}
72+
}

src/ignite/Ignite.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import type {
1111
SemverNode,
1212
CronOptions,
1313
HttpOptions,
14+
WorkerOptions,
1415
IgniteOptions,
15-
ConsoleOptions
16+
ConsoleOptions,
17+
AWSLambdaHandler
1618
} from '#src/types'
1719

1820
import { Ioc } from '@athenna/ioc'
@@ -21,13 +23,13 @@ import { Http } from '#src/applications/Http'
2123
import type { ServerImpl } from '@athenna/http'
2224
import { EnvHelper, Rc } from '@athenna/config'
2325
import { isAbsolute, resolve } from 'node:path'
26+
import { Worker } from '#src/applications/Worker'
2427
import type { ReplImpl } from '#src/repl/ReplImpl'
2528
import { Console } from '#src/applications/Console'
2629
import { CommanderHandler } from '@athenna/artisan'
2730
import { LoadHelper } from '#src/helpers/LoadHelper'
2831
import { Log, LoggerProvider } from '@athenna/logger'
2932
import { Repl as ReplApp } from '#src/applications/Repl'
30-
import type { AWSLambdaHandler } from '#src/types/AWSLambdaHandler'
3133
import { parse as semverParse, satisfies as semverSatisfies } from 'semver'
3234
import { Is, Path, File, Module, Options, Macroable } from '@athenna/common'
3335
import { NotSatisfiedNodeVersion } from '#src/exceptions/NotSatisfiedNodeVersion'
@@ -174,6 +176,21 @@ export class Ignite extends Macroable {
174176
}
175177
}
176178

179+
/**
180+
* Ignite the Worker application.
181+
*/
182+
public async worker(options?: WorkerOptions) {
183+
try {
184+
this.options.environments.push('worker')
185+
186+
await this.fire()
187+
188+
return await Worker.boot(options)
189+
} catch (err) {
190+
await this.handleError(err)
191+
}
192+
}
193+
177194
/**
178195
* Fire the application configuring the env variables file, configuration files
179196
* providers and preload files.

src/types/WorkerOptions.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* @athenna/core
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
export type WorkerOptions = {
11+
/**
12+
* The path to the worker routes.
13+
*
14+
* @default Path.routes(`worker.${Path.ext()}`)
15+
*/
16+
routePath?: string
17+
18+
/**
19+
* The path to the WorkerKernel. The worker kernel is responsible to register controllers,
20+
* all kind of middlewares, plugins and the exception handler. By default,
21+
* Athenna will use the built in Kernel. But you can do your own implementation
22+
* extending the "WorkerKernel" class from Http and setting the path to it here.
23+
*
24+
* @default '@athenna/queue/kernels/WorkerKernel'
25+
*/
26+
kernelPath?: string
27+
}

src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from '#src/types/RcOptions'
1111
export * from '#src/types/SemverNode'
1212
export * from '#src/types/CronOptions'
1313
export * from '#src/types/HttpOptions'
14+
export * from '#src/types/WorkerOptions'
1415
export * from '#src/types/IgniteOptions'
1516
export * from '#src/types/ConsoleOptions'
1617
export * from '#src/types/AWSLambdaHandler'

tests/fixtures/config/queue.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @athenna/core
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Env } from '@athenna/config'
11+
12+
export default {
13+
/*
14+
|--------------------------------------------------------------------------
15+
| Default Queue Connection Name
16+
|--------------------------------------------------------------------------
17+
|
18+
| Athenna's queue API supports an assortment of back-ends via a single
19+
| API, giving you convenient access to each back-end using the same
20+
| syntax for every one. Here you may define a default connection.
21+
|
22+
*/
23+
24+
default: Env('QUEUE_CONNECTION', 'memory'),
25+
26+
/*
27+
|--------------------------------------------------------------------------
28+
| Queue Connections
29+
|--------------------------------------------------------------------------
30+
|
31+
| Here you may configure the connection information for each server that
32+
| is used by your application. A default configuration has been added
33+
| for each back-end shipped with Athenna. You are free to add more.
34+
|
35+
| Drivers: "memory", "database", "awsSqs", "fake"
36+
|
37+
*/
38+
39+
connections: {
40+
memory: {
41+
driver: 'memory',
42+
queue: 'queue_name',
43+
deadletter: 'deadletter_queue_name',
44+
attempts: 1
45+
}
46+
}
47+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @athenna/core
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Log } from '@athenna/logger'
11+
import { WorkerKernel } from '@athenna/queue/kernels/WorkerKernel'
12+
13+
Log.info('importing CustomWorkerKernel')
14+
15+
export class CustomWorkerKernel extends WorkerKernel {}

tests/fixtures/routes/worker.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @athenna/core
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Queue } from '@athenna/queue'
11+
12+
Queue.worker()
13+
.task()
14+
.name('worker:task')
15+
.handler(() => {})
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* @athenna/core
3+
*
4+
* (c) João Lenon <lenon@athenna.io>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Worker, type Context } from '@athenna/queue'
11+
12+
@Worker()
13+
export class HelloWorker {
14+
public async handle(ctx: Context) {
15+
console.log(ctx)
16+
}
17+
}

0 commit comments

Comments
 (0)