Skip to content

Commit

Permalink
Merge pull request #227 from AthennaIO/develop
Browse files Browse the repository at this point in the history
feat: add docs for schedulers page
  • Loading branch information
jlenon7 committed Sep 8, 2024
2 parents a6166fc + 29ac2c6 commit 93632e5
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 24 deletions.
2 changes: 1 addition & 1 deletion docs/architecture-concepts/service-container.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ develop without it.
The example above is just to show that we can place our services anywhere in our
application, without depending on configuration files or any other kind of
setup. We recommend you placing your services in specifics directory and not
inside your route file. A good place to put your services is `app/services`
inside your route file. A good place to put your services is `src/services`
directory, since `make:service` command will save your services there.
But remember that this is only a tip, at the end of the day you can do
whatever you want with Athenna 😎.
Expand Down
8 changes: 4 additions & 4 deletions docs/cli-application/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ creating your own commands by extending the abstract class

In addition to the commands provided with Artisan, you may
build your own custom commands. Commands are typically stored
in the `app/console/commands` directory; however, you are
in the `src/console/commands` directory; however, you are
free to choose your own storage location as long as your
commands can be imported and registered.

To create a new command, you may use the `make:command`
Artisan command. This command will create a new command
class in the `app/console/commands` directory and register
class in the `src/console/commands` directory and register
it inside `commands` object of `.athennarc.json` file.
Don't worry if this directory does not exist in your
application—it will be created the first time you run the
Expand Down Expand Up @@ -732,7 +732,7 @@ export class Greet extends BaseCommand {

this.logger.column(data, { columns: ['MODULE', 'COUNT'] })

const path = 'app/services/Service.ts'
const path = 'src/services/Service.ts'
const action = this.logger.action('create')

action.succeeded(path)
Expand Down Expand Up @@ -884,7 +884,7 @@ actions to explain to the user what happened to some
determined operation:

```typescript
const path = 'app/services/Service.ts'
const path = 'src/services/Service.ts'
const action = this.logger.action('create')

action.succeeded(path)
Expand Down
6 changes: 3 additions & 3 deletions docs/cli-application/error-handling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This documentation will cover about error handling in the **CLI**
application, which means that only errors that happens inside
the `handle()` method of commands and bellow that will be handled:

```typescript title="app/console/commands/AppCommand.ts"
```typescript title="src/console/commands/AppCommand.ts"
import { BaseCommand } from '@athenna/artisan'
import { AppService } from '#src/services/AppService'

Expand Down Expand Up @@ -127,7 +127,7 @@ Simple exceptions are recognized by `ConsoleExceptionHandler` by
the `code`. If the code is `E_SIMPLE_CLI`, it will be considered
as a simple exception:

```typescript title="app/console/exceptions/NotFoundDatabaseExceptio.ts"
```typescript title="src/console/exceptions/NotFoundDatabaseExceptio.ts"
import { Exception } from '@athenna/common'

export class NotFoundDatabaseException extends Exception {
Expand All @@ -145,7 +145,7 @@ Let's suppose you want to write a custom logic for handling
your exceptions. You can do so by creating your own
exception handler:

```typescript title="app/console/exceptions/Handler.ts"
```typescript title="src/console/exceptions/Handler.ts"
import { ConsoleExceptionHandler } from '@athenna/artisan'

export class Handler extends ConsoleExceptionHandler {
Expand Down
14 changes: 14 additions & 0 deletions docs/cron-application/annotations.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: Annotations
sidebar_position: 3
toc_max_heading_level: 2
description: Check all available CRON annotations and it options.
---

import Path from '@site/src/components/path'

# Annotations

Check all available CRON annotations and it options.

Coming Soon...
15 changes: 15 additions & 0 deletions docs/cron-application/cron-context.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: CRON Context
sidebar_position: 2
description: Understand the purpose of the CRON context object.
---

import Path from '@site/src/components/path'

# CRON Context

Understand the purpose of the CRON context object.

## Introduction

Coming Soon...
15 changes: 15 additions & 0 deletions docs/cron-application/error-handling.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Error Handling
sidebar_position: 2
description: Understand how you can handle the errors of the CRON Application.
---

import Path from '@site/src/components/path'

# Error Handling

Understand how you can handle the errors of the CRON Application.

## Introduction

Coming Soon...
189 changes: 188 additions & 1 deletion docs/cron-application/schedulers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,197 @@ sidebar_position: 1
description: See how to create and configure your CRON job schedulers.
---

import Path from '@site/src/components/path'

# Schedulers

See how to create and configure your CRON job schedulers.

## Introduction

Coming soon...
Athenna's scheduler offers a fresh approach to managing
scheduled tasks on your server. The scheduler allows you
to fluently and expressively define your scheduler within
your Athenna application itself. When using the scheduler,
only a single cron entry is needed on your server. Your
task schedule can be defined in your application's
<Path father="routes" child="cron.ts" /> file or as a class
inside <Path father="cron" child="schedulers/MyScheduler.ts" />.

## Defining Schedulers

Schedulers are typically stored in the `src/cron/scheduelrs`
directory; however, you are free to choose your own storage
location as long as your schedulers can be imported and registered.

To create a new scheduler, you may use the `make:scheduler`
Artisan command. This command will create a new command class
in the `src/cron/schedulers` directory and register it inside
`schedulers` array of `.athennarc.json` file. Don't worry if
this directory does not exist in your application—it will be
created the first time you run the `make:scheduler` Artisan command:

```bash
node artisan make:scheduler DeleteRecentUsers
```

This will create the schedulers file and automatically register
it for you:

```json title=".athennarc.json"
{
"schedulers": [
"#src/cron/schedulers/DeleteRecentUsers" 👈
]
}
```

### Defining schedulers logic

In this example, we will schedule a `handler` method to be called
**every day at midnight**. Within the method we will execute a
database query to clear a table:

```typescript
import { Database } from '@athenna/database'
import { Scheduler, type Context } from '@athenna/cron'

@Scheduler({ pattern: '0 0 * * *' })
export class DeleteRecentUsers {
public async handler(ctx: Context) {
await Database.table('recent_users').delete()
}
}
```

:::tip

You can use [Crontab.guru](https://crontab.guru/) to help you
create your CRON pattern, or simply ask [ChatGPT](https://chatgpt.com/) 🤩.

:::

#### Defining schedulers in route file

If you prefer, you can use the <Path father="routes" child="cron.ts" />
file to register your schedulers:

```typescript
import { Cron } from '@athenna/cron'
import { Database } from '@athenna/database'

Cron.schedule().name('delete_recent_users')
.pattern('0 0 * * *')
.handler(async (ctx) => {
await Database.table('recent_users').delete()
})
```

### Listing schedulers (Coming Soon)

If you would like to view an overview of your scheduled tasks and the
next time they are scheduled to run, you may use the cron:list Artisan
command:

```shell
node artisan cron:list
```

## Running scheduler locally (Coming Soon)

When developing or even in production you might need to
force the scheduler to run. To do so you can use the
`node artisan cron:run` command:

```typescript
node artisan cron:run DeleteRecentUsers
```

You can also use a CRON pattern, this will trigger all the
schedulers registered with the same pattern:

```typescript
node artisan cron:run "0 0 * * *"
```

### Using `runOnInit` option

Another way to run your schedulers locally is to define the
`runOnInit=true` option:

```typescript
import { Database } from '@athenna/database'
import { Scheduler, type Context } from '@athenna/cron'

@Scheduler({
runOnInit: true, 👈
pattern: '0 0 * * *'
})
export class DeleteRecentUsers {
public async handler(ctx: Context) {
await Database.table('recent_users').delete()
}
}
```

If using routes you may call the `runOnInit()` method:

```typescript
import { Cron } from '@athenna/cron'
import { Database } from '@athenna/database'

Cron.schedule().name('delete_recent_users')
.runOnInit(true) 👈
.pattern('0 0 * * *')
.handler(async (ctx) => {
await Database.table('recent_users').delete()
})
```

If this option is set to `true`, it will automatically run your
scheduler when bootstrapping your Athenna application.

## Dependency injection in schedulers

When using schedulers classes you are able to use the `@Inject()`
annotation to inject dependencies from you application within your
scheduler class:

```typescript
import { Inject } from '@athenna/ioc'
import { Scheduler, type Context } from '@athenna/cron'
import { RecentUserService } from '#src/services/RecentUserService'

@Scheduler({ pattern: '0 0 * * *' })
export class DeleteRecentUsers {
@Inject()
public recentUserService: RecentUserService

public async handler(ctx: Context) {
await this.recentUserService.deleteAll()
}
}
```

### Automatic constructor injection

You can also use the automatic constructor injection if
your don't want to use the `@Inject()` annotation:

```typescript
import { Scheduler, type Context } from '@athenna/cron'
import type { RecentUserService } from '#src/services/RecentUserService'

@Scheduler({ pattern: '0 0 * * *' })
export class DeleteRecentUsers {
public recentUserService: RecentUserService

public constructor(recentUserService: RecentUserService) {
this.recentUserService = recentUserService
}

public async handler(ctx: Context) {
await this.recentUserService.deleteAll()
}
}
```
15 changes: 15 additions & 0 deletions docs/cron-application/tracing-executions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Tracing Executions
sidebar_position: 2
description: Understand how to trace executions of your CRON application.
---

import Path from '@site/src/components/path'

# Tracing Executions

Understand how to trace executions of your CRON application.

## Introduction

Coming Soon...
2 changes: 1 addition & 1 deletion docs/rest-api-application/error-handling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ Let's suppose you want to write a custom logic for handling
your exceptions. You can do so by creating your own
exception handler:

```typescript title="app/http/exceptions/Handler.ts"
```typescript title="src/http/exceptions/Handler.ts"
import { type ErrorContext, HttpExceptionHandler } from '@athenna/http'

export class Handler extends HttpExceptionHandler {
Expand Down
4 changes: 2 additions & 2 deletions docs/rest-api-application/middlewares.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ node artisan make:interceptor InterceptMiddleware
Just like `make:middleware`, Athenna will auto register the
middleware if using `make:interceptor` command. The above
command will produce the following content at
`app/http/interceptors/InterceptMiddleware.ts` file:
`src/http/interceptors/InterceptMiddleware.ts` file:

```typescript
import { Interceptor } from '@athenna/http'
Expand Down Expand Up @@ -248,7 +248,7 @@ node artisan make:terminator TerminateMiddleware
Just like `make:middleware`, Athenna will auto register the
middleware if using `make:terminator` command. The above
command will produce the following content at
`app/http/terminators/TerminateMiddleware.ts` file:
`src/http/terminators/TerminateMiddleware.ts` file:

```typescript
import { Terminator } from '@athenna/http'
Expand Down
Loading

0 comments on commit 93632e5

Please sign in to comment.