0xkobold 0.3.3 → 0.4.0
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/HEARTBEAT.md +170 -43
- package/dist/package.json +1 -1
- package/dist/src/cli/commands/cron.js +329 -0
- package/dist/src/cli/commands/cron.js.map +1 -0
- package/dist/src/cli/program.js +4 -0
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/cron/index.js +38 -0
- package/dist/src/cron/index.js.map +1 -0
- package/dist/src/cron/parser.js +294 -0
- package/dist/src/cron/parser.js.map +1 -0
- package/dist/src/cron/runner.js +243 -0
- package/dist/src/cron/runner.js.map +1 -0
- package/dist/src/cron/scheduler.js +512 -0
- package/dist/src/cron/scheduler.js.map +1 -0
- package/dist/src/cron/types.js +8 -0
- package/dist/src/cron/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron Scheduler - 0xKobold
|
|
3
|
+
*
|
|
4
|
+
* Core scheduler for cron jobs with SQLite persistence.
|
|
5
|
+
* Supports both recurring (cron expressions) and one-shot jobs.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from "events";
|
|
8
|
+
import { Database } from "bun:sqlite";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { randomInt } from "node:crypto";
|
|
12
|
+
import { parseExpression, getNextRun, parseAt, } from "./parser.js";
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
defaultTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
15
|
+
maxConcurrent: 5,
|
|
16
|
+
defaultModel: "kimi-k2.5:cloud",
|
|
17
|
+
enabled: true,
|
|
18
|
+
checkInterval: 60000, // 1 minute
|
|
19
|
+
};
|
|
20
|
+
export class CronScheduler extends EventEmitter {
|
|
21
|
+
db;
|
|
22
|
+
config;
|
|
23
|
+
checkTimer;
|
|
24
|
+
running = false;
|
|
25
|
+
activeJobs = new Map();
|
|
26
|
+
constructor(dbPath, config) {
|
|
27
|
+
super();
|
|
28
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
29
|
+
// Default to ~/.0xkobold/cron.db
|
|
30
|
+
const path = dbPath || join(homedir(), ".0xkobold", "cron.db");
|
|
31
|
+
this.db = new Database(path);
|
|
32
|
+
this.initSchema();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Initialize database schema
|
|
36
|
+
*/
|
|
37
|
+
initSchema() {
|
|
38
|
+
// Execute schema inline to avoid async loading issues
|
|
39
|
+
// The schema.sql file path resolution can be tricky, so we inline the critical tables
|
|
40
|
+
this.db.exec(`
|
|
41
|
+
-- Cron jobs table
|
|
42
|
+
CREATE TABLE IF NOT EXISTS cron_jobs (
|
|
43
|
+
id TEXT PRIMARY KEY,
|
|
44
|
+
name TEXT NOT NULL,
|
|
45
|
+
cron_expression TEXT,
|
|
46
|
+
at INTEGER,
|
|
47
|
+
at_duration INTEGER,
|
|
48
|
+
timezone TEXT DEFAULT 'UTC',
|
|
49
|
+
session_type TEXT DEFAULT 'isolated',
|
|
50
|
+
message TEXT NOT NULL,
|
|
51
|
+
model TEXT,
|
|
52
|
+
thinking_level TEXT,
|
|
53
|
+
working_dir TEXT,
|
|
54
|
+
token_limit INTEGER,
|
|
55
|
+
enabled INTEGER DEFAULT 1,
|
|
56
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
57
|
+
updated_at INTEGER DEFAULT (unixepoch()),
|
|
58
|
+
last_run_at INTEGER,
|
|
59
|
+
next_run_at INTEGER NOT NULL,
|
|
60
|
+
run_count INTEGER DEFAULT 0,
|
|
61
|
+
error_count INTEGER DEFAULT 0,
|
|
62
|
+
last_error TEXT,
|
|
63
|
+
last_output TEXT,
|
|
64
|
+
delete_after_run INTEGER DEFAULT 0,
|
|
65
|
+
wake_after_run INTEGER DEFAULT 0,
|
|
66
|
+
stagger INTEGER DEFAULT 0,
|
|
67
|
+
exact INTEGER DEFAULT 0
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
CREATE INDEX IF NOT EXISTS idx_cron_jobs_next_run
|
|
71
|
+
ON cron_jobs(next_run_at)
|
|
72
|
+
WHERE enabled = 1;
|
|
73
|
+
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_cron_jobs_last_run
|
|
75
|
+
ON cron_jobs(last_run_at);
|
|
76
|
+
|
|
77
|
+
CREATE TABLE IF NOT EXISTS cron_runs (
|
|
78
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
79
|
+
job_id TEXT NOT NULL,
|
|
80
|
+
started_at INTEGER NOT NULL,
|
|
81
|
+
completed_at INTEGER,
|
|
82
|
+
success INTEGER,
|
|
83
|
+
output TEXT,
|
|
84
|
+
tokens_used INTEGER DEFAULT 0,
|
|
85
|
+
cost REAL,
|
|
86
|
+
error TEXT,
|
|
87
|
+
exit_code INTEGER
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_cron_runs_job_id
|
|
91
|
+
ON cron_runs(job_id);
|
|
92
|
+
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_cron_runs_started
|
|
94
|
+
ON cron_runs(started_at DESC);
|
|
95
|
+
`);
|
|
96
|
+
this.emit("schema:initialized");
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Start the scheduler
|
|
100
|
+
*/
|
|
101
|
+
start() {
|
|
102
|
+
if (this.running)
|
|
103
|
+
return;
|
|
104
|
+
this.running = true;
|
|
105
|
+
this.emit("started");
|
|
106
|
+
// Initial check
|
|
107
|
+
this.checkAndRunJobs();
|
|
108
|
+
// Schedule periodic checks
|
|
109
|
+
this.checkTimer = setInterval(() => {
|
|
110
|
+
this.checkAndRunJobs();
|
|
111
|
+
}, this.config.checkInterval);
|
|
112
|
+
console.log(`[CronScheduler] Started (check interval: ${this.config.checkInterval}ms)`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Stop the scheduler
|
|
116
|
+
*/
|
|
117
|
+
stop() {
|
|
118
|
+
this.running = false;
|
|
119
|
+
if (this.checkTimer) {
|
|
120
|
+
clearInterval(this.checkTimer);
|
|
121
|
+
this.checkTimer = undefined;
|
|
122
|
+
}
|
|
123
|
+
this.emit("stopped");
|
|
124
|
+
console.log("[CronScheduler] Stopped");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check for and run due jobs
|
|
128
|
+
*/
|
|
129
|
+
async checkAndRunJobs() {
|
|
130
|
+
if (!this.running)
|
|
131
|
+
return;
|
|
132
|
+
const now = Date.now();
|
|
133
|
+
// Get jobs that should run now (respecting concurrency limit)
|
|
134
|
+
const availableSlots = this.config.maxConcurrent - this.activeJobs.size;
|
|
135
|
+
if (availableSlots <= 0) {
|
|
136
|
+
console.log("[CronScheduler] Max concurrent jobs reached, skipping check");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const jobs = this.db
|
|
140
|
+
.query(`SELECT * FROM cron_jobs
|
|
141
|
+
WHERE enabled = true
|
|
142
|
+
AND next_run_at <= ?
|
|
143
|
+
AND (last_run_at IS NULL OR last_run_at < next_run_at)
|
|
144
|
+
ORDER BY next_run_at ASC
|
|
145
|
+
LIMIT ?`)
|
|
146
|
+
.all(now, availableSlots);
|
|
147
|
+
for (const job of jobs) {
|
|
148
|
+
if (this.activeJobs.has(job.id))
|
|
149
|
+
continue;
|
|
150
|
+
// Add stagger for load distribution
|
|
151
|
+
const staggerMs = this.calculateStagger(job);
|
|
152
|
+
if (staggerMs > 0) {
|
|
153
|
+
// Job has stagger, update next_run_at but don't run yet
|
|
154
|
+
this.db.run(`UPDATE cron_jobs
|
|
155
|
+
SET next_run_at = next_run_at + ?
|
|
156
|
+
WHERE id = ?`, [staggerMs, job.id]);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
// Run the job
|
|
160
|
+
const jobPromise = this.executeJob(job);
|
|
161
|
+
this.activeJobs.set(job.id, jobPromise);
|
|
162
|
+
jobPromise
|
|
163
|
+
.then(() => {
|
|
164
|
+
this.activeJobs.delete(job.id);
|
|
165
|
+
this.emit("job:completed", job.id);
|
|
166
|
+
})
|
|
167
|
+
.catch((error) => {
|
|
168
|
+
this.activeJobs.delete(job.id);
|
|
169
|
+
console.error(`[CronScheduler] Job ${job.id} failed:`, error);
|
|
170
|
+
this.emit("job:failed", job.id, error);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Calculate stagger delay for a job
|
|
176
|
+
*/
|
|
177
|
+
calculateStagger(job) {
|
|
178
|
+
if (job.exact || !job.stagger || job.stagger <= 0) {
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
// Random delay between 0 and stagger minutes (converted to ms)
|
|
182
|
+
return randomInt(0, job.stagger * 60 * 1000);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Execute a single job
|
|
186
|
+
*/
|
|
187
|
+
async executeJob(job) {
|
|
188
|
+
const runId = this.logJobStart(job.id);
|
|
189
|
+
const startTime = Date.now();
|
|
190
|
+
try {
|
|
191
|
+
// Import runner dynamically to avoid circular deps
|
|
192
|
+
const { runJobRunner } = await import("./runner.js");
|
|
193
|
+
const result = await runJobRunner(job);
|
|
194
|
+
const duration = Date.now() - startTime;
|
|
195
|
+
// Log completion
|
|
196
|
+
this.logJobComplete(runId, result, duration);
|
|
197
|
+
// Update job stats
|
|
198
|
+
this.updateJobAfterRun(job, result, duration);
|
|
199
|
+
// Handle wake
|
|
200
|
+
if (job.wakeAfterRun && result.success) {
|
|
201
|
+
this.emit("job:wake", job.id, result.output);
|
|
202
|
+
}
|
|
203
|
+
// Handle delete for one-shots
|
|
204
|
+
if (job.deleteAfterRun) {
|
|
205
|
+
this.removeJob(job.id, false);
|
|
206
|
+
this.emit("job:deleted", job.id);
|
|
207
|
+
}
|
|
208
|
+
this.emit("job:success", job.id, result);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
const duration = Date.now() - startTime;
|
|
212
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
213
|
+
this.logJobError(runId, errorMsg);
|
|
214
|
+
this.updateJobError(job, errorMsg);
|
|
215
|
+
this.emit("job:error", job.id, error);
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Add a new job
|
|
221
|
+
*/
|
|
222
|
+
addJob(options) {
|
|
223
|
+
const id = `cron:${Date.now()}:${randomInt(1000, 9999)}`;
|
|
224
|
+
const session = options.session || "isolated";
|
|
225
|
+
const timezone = options.timezone || this.config.defaultTimezone;
|
|
226
|
+
let nextRunAt;
|
|
227
|
+
let cronExpression;
|
|
228
|
+
let at;
|
|
229
|
+
let atDuration;
|
|
230
|
+
if (options.cron) {
|
|
231
|
+
// Recurring job
|
|
232
|
+
cronExpression = options.cron;
|
|
233
|
+
const expr = parseExpression(options.cron, timezone);
|
|
234
|
+
nextRunAt = getNextRun(expr).getTime();
|
|
235
|
+
}
|
|
236
|
+
else if (options.at) {
|
|
237
|
+
// One-shot job
|
|
238
|
+
const atTime = parseAt(options.at);
|
|
239
|
+
if (atTime > Date.now() + 365 * 24 * 60 * 60 * 1000) {
|
|
240
|
+
// Likely an absolute timestamp
|
|
241
|
+
at = atTime;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// Relative duration
|
|
245
|
+
atDuration = atTime - Date.now();
|
|
246
|
+
at = atTime;
|
|
247
|
+
}
|
|
248
|
+
nextRunAt = atTime;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
throw new Error("Either --cron or --at is required");
|
|
252
|
+
}
|
|
253
|
+
const job = {
|
|
254
|
+
id,
|
|
255
|
+
name: options.name,
|
|
256
|
+
cronExpression,
|
|
257
|
+
at,
|
|
258
|
+
atDuration,
|
|
259
|
+
session,
|
|
260
|
+
message: options.message,
|
|
261
|
+
model: options.model,
|
|
262
|
+
thinkingLevel: options.thinkingLevel,
|
|
263
|
+
timezone,
|
|
264
|
+
enabled: true,
|
|
265
|
+
createdAt: Date.now(),
|
|
266
|
+
nextRunAt,
|
|
267
|
+
runCount: 0,
|
|
268
|
+
errorCount: 0,
|
|
269
|
+
deleteAfterRun: options.deleteAfterRun,
|
|
270
|
+
wakeAfterRun: options.wake,
|
|
271
|
+
workingDir: options.workingDir,
|
|
272
|
+
};
|
|
273
|
+
// Insert into database
|
|
274
|
+
this.db.run(`INSERT INTO cron_jobs (
|
|
275
|
+
id, name, cron_expression, at, at_duration, timezone,
|
|
276
|
+
session_type, message, model, thinking_level, working_dir, token_limit,
|
|
277
|
+
enabled, created_at, next_run_at, run_count, error_count,
|
|
278
|
+
delete_after_run, wake_after_run
|
|
279
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
280
|
+
job.id,
|
|
281
|
+
job.name,
|
|
282
|
+
job.cronExpression || null,
|
|
283
|
+
job.at || null,
|
|
284
|
+
job.atDuration || null,
|
|
285
|
+
job.timezone,
|
|
286
|
+
job.session,
|
|
287
|
+
job.message,
|
|
288
|
+
job.model || null,
|
|
289
|
+
job.thinkingLevel || null,
|
|
290
|
+
job.workingDir || null,
|
|
291
|
+
job.tokenLimit || null,
|
|
292
|
+
job.enabled ? 1 : 0,
|
|
293
|
+
job.createdAt,
|
|
294
|
+
job.nextRunAt,
|
|
295
|
+
job.runCount,
|
|
296
|
+
job.errorCount,
|
|
297
|
+
job.deleteAfterRun ? 1 : 0,
|
|
298
|
+
job.wakeAfterRun ? 1 : 0,
|
|
299
|
+
]);
|
|
300
|
+
this.emit("job:added", job);
|
|
301
|
+
console.log(`[CronScheduler] Added job: ${job.name} (${job.id})`);
|
|
302
|
+
return job;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Remove a job
|
|
306
|
+
*/
|
|
307
|
+
removeJob(id, log = true) {
|
|
308
|
+
const result = this.db.run("DELETE FROM cron_jobs WHERE id = ?", [id]);
|
|
309
|
+
if (result.changes > 0) {
|
|
310
|
+
if (log) {
|
|
311
|
+
this.emit("job:removed", id);
|
|
312
|
+
console.log(`[CronScheduler] Removed job: ${id}`);
|
|
313
|
+
}
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Enable a job
|
|
320
|
+
*/
|
|
321
|
+
enableJob(id) {
|
|
322
|
+
const result = this.db.run("UPDATE cron_jobs SET enabled = 1 WHERE id = ?", [id]);
|
|
323
|
+
if (result.changes > 0) {
|
|
324
|
+
this.emit("job:enabled", id);
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Disable a job
|
|
331
|
+
*/
|
|
332
|
+
disableJob(id) {
|
|
333
|
+
const result = this.db.run("UPDATE cron_jobs SET enabled = 0 WHERE id = ?", [id]);
|
|
334
|
+
if (result.changes > 0) {
|
|
335
|
+
this.emit("job:disabled", id);
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Get a job by ID
|
|
342
|
+
*/
|
|
343
|
+
getJob(id) {
|
|
344
|
+
return this.db.query("SELECT * FROM cron_jobs WHERE id = ?").get(id);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* List all jobs
|
|
348
|
+
*/
|
|
349
|
+
listJobs() {
|
|
350
|
+
return this.db.query("SELECT * FROM cron_jobs ORDER BY created_at DESC").all();
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get job status for CLI display
|
|
354
|
+
*/
|
|
355
|
+
getJobStatus() {
|
|
356
|
+
return this.db.query(`
|
|
357
|
+
SELECT
|
|
358
|
+
id,
|
|
359
|
+
name,
|
|
360
|
+
CASE
|
|
361
|
+
WHEN cron_expression IS NOT NULL THEN cron_expression
|
|
362
|
+
ELSE 'one-shot'
|
|
363
|
+
END as schedule,
|
|
364
|
+
datetime(next_run_at / 1000, 'unixepoch') as nextRun,
|
|
365
|
+
session_type as session,
|
|
366
|
+
CASE
|
|
367
|
+
WHEN enabled = 0 THEN 'disabled'
|
|
368
|
+
ELSE 'enabled'
|
|
369
|
+
END as status,
|
|
370
|
+
datetime(last_run_at / 1000, 'unixepoch') as lastRun,
|
|
371
|
+
run_count as runCount
|
|
372
|
+
FROM cron_jobs
|
|
373
|
+
ORDER BY next_run_at ASC
|
|
374
|
+
`).all();
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get upcoming jobs
|
|
378
|
+
*/
|
|
379
|
+
getUpcoming(limit = 10) {
|
|
380
|
+
return this.db.query(`
|
|
381
|
+
SELECT * FROM cron_jobs
|
|
382
|
+
WHERE enabled = true
|
|
383
|
+
AND next_run_at > ?
|
|
384
|
+
ORDER BY next_run_at ASC
|
|
385
|
+
LIMIT ${limit}
|
|
386
|
+
`).all(Date.now());
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Get job run history
|
|
390
|
+
*/
|
|
391
|
+
getJobHistory(jobId, limit = 10) {
|
|
392
|
+
return this.db.query(`
|
|
393
|
+
SELECT * FROM cron_runs
|
|
394
|
+
WHERE job_id = ?
|
|
395
|
+
ORDER BY started_at DESC
|
|
396
|
+
LIMIT ?
|
|
397
|
+
`).all(jobId, limit);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Log job start
|
|
401
|
+
*/
|
|
402
|
+
logJobStart(jobId) {
|
|
403
|
+
const result = this.db.run("INSERT INTO cron_runs (job_id, started_at) VALUES (?, ?)", [jobId, Date.now()]);
|
|
404
|
+
return result.lastInsertRowid;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Log job completion
|
|
408
|
+
*/
|
|
409
|
+
logJobComplete(runId, result, duration) {
|
|
410
|
+
this.db.run(`UPDATE cron_runs
|
|
411
|
+
SET completed_at = ?, success = ?, output = ?, tokens_used = ?, cost = ?
|
|
412
|
+
WHERE id = ?`, [
|
|
413
|
+
Date.now(),
|
|
414
|
+
result.success ? 1 : 0,
|
|
415
|
+
result.output,
|
|
416
|
+
result.tokensUsed,
|
|
417
|
+
result.cost || null,
|
|
418
|
+
runId,
|
|
419
|
+
]);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Log job error
|
|
423
|
+
*/
|
|
424
|
+
logJobError(runId, error) {
|
|
425
|
+
this.db.run(`UPDATE cron_runs
|
|
426
|
+
SET completed_at = ?, success = 0, error = ?
|
|
427
|
+
WHERE id = ?`, [Date.now(), error, runId]);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Update job after successful run
|
|
431
|
+
*/
|
|
432
|
+
updateJobAfterRun(job, result, duration) {
|
|
433
|
+
// Calculate next run for recurring jobs
|
|
434
|
+
let nextRunAt = null;
|
|
435
|
+
if (job.cronExpression) {
|
|
436
|
+
// Recurring: calculate next run from cron
|
|
437
|
+
const expr = parseExpression(job.cronExpression, job.timezone);
|
|
438
|
+
nextRunAt = getNextRun(expr, new Date()).getTime();
|
|
439
|
+
}
|
|
440
|
+
else if (!job.deleteAfterRun) {
|
|
441
|
+
// One-shot that shouldn't delete - disable it
|
|
442
|
+
this.disableJob(job.id);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
this.db.run(`UPDATE cron_jobs
|
|
446
|
+
SET last_run_at = ?,
|
|
447
|
+
next_run_at = ?,
|
|
448
|
+
run_count = run_count + 1,
|
|
449
|
+
last_output = ?
|
|
450
|
+
WHERE id = ?`, [
|
|
451
|
+
Date.now(),
|
|
452
|
+
nextRunAt,
|
|
453
|
+
result.output.substring(0, 1000), // Truncate for storage
|
|
454
|
+
job.id,
|
|
455
|
+
]);
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Update job after error
|
|
459
|
+
*/
|
|
460
|
+
updateJobError(job, error) {
|
|
461
|
+
// For recurring jobs, calculate next run
|
|
462
|
+
let nextRunAt = null;
|
|
463
|
+
if (job.cronExpression) {
|
|
464
|
+
const expr = parseExpression(job.cronExpression, job.timezone);
|
|
465
|
+
nextRunAt = getNextRun(expr, new Date()).getTime();
|
|
466
|
+
}
|
|
467
|
+
this.db.run(`UPDATE cron_jobs
|
|
468
|
+
SET error_count = error_count + 1,
|
|
469
|
+
last_error = ?,
|
|
470
|
+
next_run_at = COALESCE(?, next_run_at)
|
|
471
|
+
WHERE id = ?`, [error.substring(0, 500), nextRunAt, job.id]);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get scheduler statistics
|
|
475
|
+
*/
|
|
476
|
+
getStats() {
|
|
477
|
+
const totalJobs = this.db.query("SELECT COUNT(*) as count FROM cron_jobs").get().count;
|
|
478
|
+
const enabledJobs = this.db.query("SELECT COUNT(*) as count FROM cron_jobs WHERE enabled = 1").get().count;
|
|
479
|
+
const totalRuns = this.db.query("SELECT COUNT(*) as count FROM cron_runs").get().count;
|
|
480
|
+
const successfulRuns = this.db.query("SELECT COUNT(*) as count FROM cron_runs WHERE success = 1").get().count;
|
|
481
|
+
return {
|
|
482
|
+
totalJobs,
|
|
483
|
+
enabledJobs,
|
|
484
|
+
activeJobs: this.activeJobs.size,
|
|
485
|
+
totalRuns,
|
|
486
|
+
successfulRuns,
|
|
487
|
+
failedRuns: totalRuns - successfulRuns,
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Close database connection
|
|
492
|
+
*/
|
|
493
|
+
close() {
|
|
494
|
+
this.stop();
|
|
495
|
+
this.db.close();
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// Singleton instance
|
|
499
|
+
let schedulerInstance = null;
|
|
500
|
+
export function getCronScheduler(dbPath, config) {
|
|
501
|
+
if (!schedulerInstance) {
|
|
502
|
+
schedulerInstance = new CronScheduler(dbPath, config);
|
|
503
|
+
}
|
|
504
|
+
return schedulerInstance;
|
|
505
|
+
}
|
|
506
|
+
export function resetCronScheduler() {
|
|
507
|
+
if (schedulerInstance) {
|
|
508
|
+
schedulerInstance.close();
|
|
509
|
+
schedulerInstance = null;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/cron/scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/cron/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "0xkobold",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Your digital familiar - a personal AI assistant that learns and evolves (v0.3.0 - Multi-Channel, Security, Media Support)",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|