@gravito/horizon 1.0.0-alpha.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/README.md +141 -0
- package/dist/index.cjs +6371 -0
- package/dist/index.mjs +6345 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @gravito/horizon
|
|
2
|
+
|
|
3
|
+
Enterprise-grade distributed task scheduler for Gravito framework.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Fluent API**: Expressive syntax for defining task schedules (e.g. `.daily().at('14:00')`).
|
|
8
|
+
- **Distributed Locking**: Prevents duplicate task execution across multiple servers (supports Memory, Cache, Redis).
|
|
9
|
+
- **Cron Integration**: Designed to be triggered by a single system cron entry.
|
|
10
|
+
- **Hooks**: Events for task success/failure.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun add @gravito/horizon
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
1. Register the orbit in your application boot:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { OrbitHorizon } from '@gravito/horizon'
|
|
24
|
+
import { OrbitCache } from '@gravito/stasis' // Optional, for cache lock
|
|
25
|
+
|
|
26
|
+
await PlanetCore.boot({
|
|
27
|
+
config: {
|
|
28
|
+
scheduler: {
|
|
29
|
+
lock: { driver: 'cache' },
|
|
30
|
+
nodeRole: 'worker' // 'api', 'web', etc.
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
orbits: [
|
|
34
|
+
OrbitCache, // Load cache first if using cache driver
|
|
35
|
+
OrbitHorizon
|
|
36
|
+
]
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Schedule tasks:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// Access scheduler from core services or context
|
|
44
|
+
const scheduler = core.services.get('scheduler')
|
|
45
|
+
|
|
46
|
+
scheduler.task('daily-cleanup', async () => {
|
|
47
|
+
await db.cleanup()
|
|
48
|
+
})
|
|
49
|
+
.daily()
|
|
50
|
+
.at('02:00')
|
|
51
|
+
.onOneServer() // Distributed lock
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Distributed Locking
|
|
55
|
+
|
|
56
|
+
To prevent tasks from running simultaneously on multiple servers, use `onOneServer()` (or `withoutOverlapping()`).
|
|
57
|
+
The default lock driver is `memory` (single server), but you should configure `cache` or `redis` for distributed setups.
|
|
58
|
+
|
|
59
|
+
## CLI Usage
|
|
60
|
+
|
|
61
|
+
The Gravito CLI provides commands to run and manage your scheduled tasks.
|
|
62
|
+
|
|
63
|
+
### List Tasks
|
|
64
|
+
View all registered tasks and their schedules:
|
|
65
|
+
```bash
|
|
66
|
+
bun run gravito schedule:list
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Run (Cron Mode)
|
|
70
|
+
Add this command to your system's crontab (e.g., `crontab -e`) to run every minute:
|
|
71
|
+
```bash
|
|
72
|
+
* * * * * cd /path/to/project && bun run gravito schedule:run
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Run (Daemon Mode)
|
|
76
|
+
If you prefer a long-running process (e.g., in Docker or specific worker environments):
|
|
77
|
+
```bash
|
|
78
|
+
bun run gravito schedule:work
|
|
79
|
+
```
|
|
80
|
+
This will poll every minute to execute due tasks.
|
|
81
|
+
|
|
82
|
+
### Entry Point
|
|
83
|
+
By default, commands look for `src/index.ts`. If your bootstrap file is elsewhere, use `--entry`:
|
|
84
|
+
```bash
|
|
85
|
+
gravito schedule:list --entry src/bootstrap.ts
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Performance Monitoring
|
|
89
|
+
|
|
90
|
+
The scheduler emits hooks providing execution metrics. You can listen to these events via `core.hooks`:
|
|
91
|
+
|
|
92
|
+
| Hook | Payload | Description |
|
|
93
|
+
|------|---------|-------------|
|
|
94
|
+
| `scheduler:run:start` | `{ date }` | Scheduler checks started |
|
|
95
|
+
| `scheduler:run:complete` | `{ date, dueCount }` | Scheduler checks completed |
|
|
96
|
+
| `scheduler:task:start` | `{ name, startTime }` | Individual task execution started |
|
|
97
|
+
| `scheduler:task:success` | `{ name, duration }` | Task completed successfully |
|
|
98
|
+
| `scheduler:task:failure` | `{ name, error, duration }` | Task failed |
|
|
99
|
+
|
|
100
|
+
## Optimizations
|
|
101
|
+
|
|
102
|
+
### Lightweight Execution
|
|
103
|
+
This package includes a lightweight, dependency-free cron parser (`SimpleCronParser`) for standard cron expressions (e.g. `* * * * *`, `0 0 * * *`). The heavy `cron-parser` library is only lazy-loaded when complex expressions are encountered, keeping your runtime memory footprint minimal.
|
|
104
|
+
|
|
105
|
+
## Process Execution & Node Roles
|
|
106
|
+
|
|
107
|
+
You can also run shell commands and restrict tasks to specific node roles (e.g., `api` vs `worker`).
|
|
108
|
+
|
|
109
|
+
### Configuration
|
|
110
|
+
|
|
111
|
+
Add `nodeRole` to your configuration:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
config: {
|
|
115
|
+
scheduler: {
|
|
116
|
+
nodeRole: 'worker'
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Mode A: Broadcast (Maintenance)
|
|
122
|
+
|
|
123
|
+
Run on EVERY node that matches the role. Useful for machine-specific maintenance.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Clean temp files on ALL 'api' nodes
|
|
127
|
+
scheduler.exec('clean-tmp', 'rm -rf /tmp/*')
|
|
128
|
+
.daily()
|
|
129
|
+
.onNode('api')
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Mode B: Single-point (Task)
|
|
133
|
+
|
|
134
|
+
Run on ONE matching node only. Useful for centralized jobs like DB migrations or reports.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Run migration on ONE 'worker' node
|
|
138
|
+
scheduler.exec('migrate', 'bun run db:migrate')
|
|
139
|
+
.onNode('worker')
|
|
140
|
+
.onOneServer()
|
|
141
|
+
```
|