Revert "feat(scheduler): Support sub-hour interval_minutes in task_schedules"
This reverts commit b607fd7f44.
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
-- Migration 121: Add interval_minutes to task_schedules for sub-hour scheduling
|
|
||||||
-- Part of Real-Time Inventory Tracking feature
|
|
||||||
-- Created: 2024-12-14
|
|
||||||
|
|
||||||
-- Add interval_minutes column for sub-hour scheduling (15min, 30min, etc.)
|
|
||||||
-- When set, takes precedence over interval_hours
|
|
||||||
ALTER TABLE task_schedules ADD COLUMN IF NOT EXISTS interval_minutes INT DEFAULT NULL;
|
|
||||||
|
|
||||||
-- Add comment for documentation
|
|
||||||
COMMENT ON COLUMN task_schedules.interval_minutes IS 'Sub-hour scheduling interval in minutes (takes precedence over interval_hours when set)';
|
|
||||||
|
|
||||||
-- Create index for finding schedules by interval type
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_task_schedules_interval_minutes
|
|
||||||
ON task_schedules(interval_minutes)
|
|
||||||
WHERE interval_minutes IS NOT NULL;
|
|
||||||
@@ -22,7 +22,6 @@ interface TaskSchedule {
|
|||||||
role: TaskRole;
|
role: TaskRole;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
interval_hours: number;
|
interval_hours: number;
|
||||||
interval_minutes: number | null; // For sub-hour scheduling (takes precedence over interval_hours)
|
|
||||||
last_run_at: Date | null;
|
last_run_at: Date | null;
|
||||||
next_run_at: Date | null;
|
next_run_at: Date | null;
|
||||||
state_code: string | null;
|
state_code: string | null;
|
||||||
@@ -168,66 +167,28 @@ class TaskScheduler {
|
|||||||
console.log(`[TaskScheduler] Schedule ${schedule.name} created ${tasksCreated} tasks`);
|
console.log(`[TaskScheduler] Schedule ${schedule.name} created ${tasksCreated} tasks`);
|
||||||
|
|
||||||
// Per TASK_WORKFLOW_2024-12-10.md: Update last_run_at and calculate next_run_at
|
// Per TASK_WORKFLOW_2024-12-10.md: Update last_run_at and calculate next_run_at
|
||||||
// Prefer interval_minutes over interval_hours for sub-hour scheduling
|
await client.query(`
|
||||||
// Add jitter (0-20% of interval) to prevent predictable crawl patterns
|
UPDATE task_schedules
|
||||||
let nextRunQuery: string;
|
SET
|
||||||
let nextRunParams: any[];
|
last_run_at = NOW(),
|
||||||
|
next_run_at = NOW() + ($1 || ' hours')::interval,
|
||||||
if (schedule.interval_minutes) {
|
last_task_count = $2,
|
||||||
// Sub-hour scheduling with jitter
|
updated_at = NOW()
|
||||||
const jitterMinutes = Math.floor(Math.random() * (schedule.interval_minutes * 0.2));
|
WHERE id = $3
|
||||||
const totalMinutes = schedule.interval_minutes + jitterMinutes;
|
`, [schedule.interval_hours, tasksCreated, schedule.id]);
|
||||||
nextRunQuery = `
|
|
||||||
UPDATE task_schedules
|
|
||||||
SET
|
|
||||||
last_run_at = NOW(),
|
|
||||||
next_run_at = NOW() + ($1 || ' minutes')::interval,
|
|
||||||
last_task_count = $2,
|
|
||||||
updated_at = NOW()
|
|
||||||
WHERE id = $3
|
|
||||||
`;
|
|
||||||
nextRunParams = [totalMinutes, tasksCreated, schedule.id];
|
|
||||||
console.log(`[TaskScheduler] Schedule ${schedule.name} next run in ${totalMinutes}min (${schedule.interval_minutes}min + ${jitterMinutes}min jitter)`);
|
|
||||||
} else {
|
|
||||||
// Standard hour-based scheduling
|
|
||||||
nextRunQuery = `
|
|
||||||
UPDATE task_schedules
|
|
||||||
SET
|
|
||||||
last_run_at = NOW(),
|
|
||||||
next_run_at = NOW() + ($1 || ' hours')::interval,
|
|
||||||
last_task_count = $2,
|
|
||||||
updated_at = NOW()
|
|
||||||
WHERE id = $3
|
|
||||||
`;
|
|
||||||
nextRunParams = [schedule.interval_hours, tasksCreated, schedule.id];
|
|
||||||
}
|
|
||||||
|
|
||||||
await client.query(nextRunQuery, nextRunParams);
|
|
||||||
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error(`[TaskScheduler] Schedule ${schedule.name} failed:`, err.message);
|
console.error(`[TaskScheduler] Schedule ${schedule.name} failed:`, err.message);
|
||||||
|
|
||||||
// Still update next_run_at to prevent infinite retry loop
|
// Still update next_run_at to prevent infinite retry loop
|
||||||
// Use interval_minutes if set, otherwise interval_hours
|
await client.query(`
|
||||||
if (schedule.interval_minutes) {
|
UPDATE task_schedules
|
||||||
await client.query(`
|
SET
|
||||||
UPDATE task_schedules
|
next_run_at = NOW() + ($1 || ' hours')::interval,
|
||||||
SET
|
last_error = $2,
|
||||||
next_run_at = NOW() + ($1 || ' minutes')::interval,
|
updated_at = NOW()
|
||||||
last_error = $2,
|
WHERE id = $3
|
||||||
updated_at = NOW()
|
`, [schedule.interval_hours, err.message, schedule.id]);
|
||||||
WHERE id = $3
|
|
||||||
`, [schedule.interval_minutes, err.message, schedule.id]);
|
|
||||||
} else {
|
|
||||||
await client.query(`
|
|
||||||
UPDATE task_schedules
|
|
||||||
SET
|
|
||||||
next_run_at = NOW() + ($1 || ' hours')::interval,
|
|
||||||
last_error = $2,
|
|
||||||
updated_at = NOW()
|
|
||||||
WHERE id = $3
|
|
||||||
`, [schedule.interval_hours, err.message, schedule.id]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,37 +511,33 @@ class TaskScheduler {
|
|||||||
try {
|
try {
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
SELECT
|
SELECT
|
||||||
ts.id,
|
id,
|
||||||
ts.name,
|
name,
|
||||||
ts.role,
|
role,
|
||||||
ts.enabled,
|
enabled,
|
||||||
ts.interval_hours,
|
interval_hours,
|
||||||
ts.interval_minutes,
|
last_run_at,
|
||||||
ts.last_run_at,
|
next_run_at,
|
||||||
ts.next_run_at,
|
state_code,
|
||||||
ts.state_code,
|
priority,
|
||||||
ts.dispensary_id,
|
method,
|
||||||
ts.priority,
|
COALESCE(is_immutable, false) as is_immutable,
|
||||||
ts.method,
|
description,
|
||||||
COALESCE(ts.is_immutable, false) as is_immutable,
|
platform,
|
||||||
ts.description,
|
last_task_count,
|
||||||
ts.platform,
|
last_error,
|
||||||
ts.last_task_count,
|
created_at,
|
||||||
ts.last_error,
|
updated_at
|
||||||
ts.created_at,
|
FROM task_schedules
|
||||||
ts.updated_at,
|
|
||||||
d.name as dispensary_name
|
|
||||||
FROM task_schedules ts
|
|
||||||
LEFT JOIN dispensaries d ON ts.dispensary_id = d.id
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE ts.role
|
CASE role
|
||||||
WHEN 'store_discovery' THEN 1
|
WHEN 'store_discovery' THEN 1
|
||||||
WHEN 'product_discovery' THEN 2
|
WHEN 'product_discovery' THEN 2
|
||||||
WHEN 'analytics_refresh' THEN 3
|
WHEN 'analytics_refresh' THEN 3
|
||||||
ELSE 4
|
ELSE 4
|
||||||
END,
|
END,
|
||||||
ts.state_code NULLS FIRST,
|
state_code NULLS FIRST,
|
||||||
ts.name
|
name
|
||||||
`);
|
`);
|
||||||
return result.rows as TaskSchedule[];
|
return result.rows as TaskSchedule[];
|
||||||
} catch {
|
} catch {
|
||||||
@@ -604,8 +561,8 @@ class TaskScheduler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a schedule
|
* Update a schedule
|
||||||
* Allows updating: enabled, interval_hours, interval_minutes, priority
|
* Allows updating: enabled, interval_hours, priority
|
||||||
* Does NOT allow updating: name, role, state_code, dispensary_id, is_immutable
|
* Does NOT allow updating: name, role, state_code, is_immutable
|
||||||
*/
|
*/
|
||||||
async updateSchedule(id: number, updates: Partial<TaskSchedule>): Promise<void> {
|
async updateSchedule(id: number, updates: Partial<TaskSchedule>): Promise<void> {
|
||||||
const setClauses: string[] = [];
|
const setClauses: string[] = [];
|
||||||
@@ -620,11 +577,6 @@ class TaskScheduler {
|
|||||||
setClauses.push(`interval_hours = $${paramIndex++}`);
|
setClauses.push(`interval_hours = $${paramIndex++}`);
|
||||||
values.push(updates.interval_hours);
|
values.push(updates.interval_hours);
|
||||||
}
|
}
|
||||||
// Allow setting interval_minutes (can be null to disable sub-hour scheduling)
|
|
||||||
if ('interval_minutes' in updates) {
|
|
||||||
setClauses.push(`interval_minutes = $${paramIndex++}`);
|
|
||||||
values.push(updates.interval_minutes);
|
|
||||||
}
|
|
||||||
if (updates.priority !== undefined) {
|
if (updates.priority !== undefined) {
|
||||||
setClauses.push(`priority = $${paramIndex++}`);
|
setClauses.push(`priority = $${paramIndex++}`);
|
||||||
values.push(updates.priority);
|
values.push(updates.priority);
|
||||||
|
|||||||
Reference in New Issue
Block a user