Skip to content

Commit

Permalink
Merge pull request #233 from AthennaIO/develop
Browse files Browse the repository at this point in the history
feat(cron): add cron application
  • Loading branch information
jlenon7 authored Aug 25, 2024
2 parents a6c8952 + 55b4a41 commit dfdeafe
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 8 deletions.
31 changes: 29 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/core",
"version": "4.45.0",
"version": "4.46.0",
"description": "One foundation for multiple applications.",
"license": "MIT",
"author": "João Lenon <[email protected]>",
Expand All @@ -15,6 +15,9 @@
"rest-api",
"http-server",
"console",
"cron",
"cronjob",
"scheduler",
"ignite",
"nodejs",
"athenna",
Expand Down Expand Up @@ -80,6 +83,7 @@
"@athenna/artisan": "^4.45.0",
"@athenna/common": "^4.46.0",
"@athenna/config": "^4.27.0",
"@athenna/cron": "^4.1.0",
"@athenna/http": "^4.41.0",
"@athenna/ioc": "^4.27.0",
"@athenna/logger": "^4.29.0",
Expand Down Expand Up @@ -218,6 +222,9 @@
"directories": {
"bootstrap": "bin"
},
"schedulers": [
"#tests/fixtures/schedulers/HelloScheduler"
],
"commands": {
"make:exception": {
"path": "#src/commands/MakeExceptionCommand"
Expand Down
67 changes: 67 additions & 0 deletions src/applications/Cron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @athenna/core
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { debug } from '#src/debug'
import { Log } from '@athenna/logger'
import type { CronImpl } from '@athenna/cron'
import { Path, Module, Options } from '@athenna/common'
import type { CronOptions } from '#src/types/CronOptions'

export class Cron {
/**
* Boot the Cron application.
*/
public static async boot(options?: CronOptions): Promise<CronImpl> {
options = Options.create(options, {
trace: Config.get('cron.trace', false),
routePath: Path.routes(`cron.${Path.ext()}`),
kernelPath: '@athenna/cron/kernels/CronKernel'
})

const cron = ioc.safeUse('Athenna/Core/Cron')

debug('booting cron application with options %o', options)

await this.resolveKernel(options)

if (Config.notExists('rc.bootLogs') || Config.is('rc.bootLogs', false)) {
return cron
}

Log.channelOrVanilla('application').success(
`Cron application successfully started`
)

return cron
}

/**
* Resolve the kernel by importing it and calling the methods to register
* schedulers, plugins and exception handler.
*/
private static async resolveKernel(options?: CronOptions) {
const Kernel = await Module.resolve(
options.kernelPath,
Config.get('rc.parentURL')
)

const kernel = new Kernel()

await kernel.registerRTracer(options.trace)
await kernel.registerExceptionHandler(options.exceptionHandlerPath)
await kernel.registerSchedulers()
await kernel.registerRoutes(options.routePath)

if (Config.is('rc.bootLogs', true)) {
Log.channelOrVanilla('application').success(
`Kernel ({yellow} ${Kernel.name}) successfully booted`
)
}
}
}
21 changes: 19 additions & 2 deletions src/ignite/Ignite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
*/

import type {
SemverNode,
CronOptions,
HttpOptions,
ConsoleOptions,
IgniteOptions,
SemverNode
ConsoleOptions
} from '#src/types'

import { Ioc } from '@athenna/ioc'
import { Cron } from '#src/applications/Cron'
import { Http } from '#src/applications/Http'
import { EnvHelper, Rc } from '@athenna/config'
import { isAbsolute, resolve } from 'node:path'
Expand Down Expand Up @@ -147,6 +149,21 @@ export class Ignite {
}
}

/**
* Ignite the CRON application.
*/
public async cron(options?: CronOptions) {
try {
this.options.environments.push('cron')

await this.fire()

return await Cron.boot(options)
} catch (err) {
await this.handleError(err)
}
}

/**
* Fire the application configuring the env variables file, configuration files
* providers and preload files.
Expand Down
45 changes: 45 additions & 0 deletions src/types/CronOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @athenna/core
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

export type CronOptions = {
/**
* Create a custom trace uuid to all new requests done to the server using AsyncLocalStorage.
*
* @default Config.get('cron.trace', false)
*/
trace?: boolean

/**
* The path to the cron routes.
*
* @default Path.routes(`cron.${Path.ext()}`)
*/
routePath?: string

/**
* The path to the CronKernel. The cron kernel is responsible to register controllers,
* all kind of middlewares, plugins and the exception handler. By default,
* Athenna will use the built in Kernel. But you can do your own implementation
* extending the "CronKernel" class from Http and setting the path to it here.
*
* @default '@athenna/cron/kernels/CronKernel'
*/
kernelPath?: string

/**
* The path to the exception handler of cron schedulers. The exception
* handler is responsible to handle all the exception that are throwed
* inside route handlers. By default, Athenna will use the built in exception
* handler. But you can do your own implementation extending the
* "CronExceptionHandler" class from Http and setting the path to it here.
*
* @default '@athenna/cron/handlers/CronExceptionHandler'
*/
exceptionHandlerPath?: string
}
7 changes: 4 additions & 3 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
* file that was distributed with this source code.
*/

export * from '#src/types/ConsoleOptions'
export * from '#src/types/HttpOptions'
export * from '#src/types/IgniteOptions'
export * from '#src/types/RcOptions'
export * from '#src/types/SemverNode'
export * from '#src/types/CronOptions'
export * from '#src/types/HttpOptions'
export * from '#src/types/IgniteOptions'
export * from '#src/types/ConsoleOptions'
15 changes: 15 additions & 0 deletions tests/fixtures/handlers/CustomCronExceptionHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @athenna/core
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Log } from '@athenna/logger'
import { ConsoleExceptionHandler } from '@athenna/artisan'

Log.info('importing CustomCronExceptionHandler')

export class CustomCronExceptionHandler extends ConsoleExceptionHandler {}
15 changes: 15 additions & 0 deletions tests/fixtures/kernels/CustomCronKernel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @athenna/core
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Log } from '@athenna/logger'
import { CronKernel } from '@athenna/cron'

Log.info('importing CustomCronKernel')

export class CustomCronKernel extends CronKernel {}
14 changes: 14 additions & 0 deletions tests/fixtures/routes/cron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @athenna/core
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Cron } from '@athenna/cron'

Cron.schedule()
.pattern('* * * * *')
.handler(() => {})
17 changes: 17 additions & 0 deletions tests/fixtures/schedulers/HelloScheduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @athenna/core
*
* (c) João Lenon <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Scheduler, type Context } from '@athenna/cron'

@Scheduler({ pattern: '* * * * *' })
export class HelloScheduler {
public async handle(ctx: Context) {
console.log(ctx)
}
}
Loading

0 comments on commit dfdeafe

Please sign in to comment.