문서 / 크론과 정기 실행
크론과 정기 실행
UTC 스케줄 등록, 내부 호출 보호와 반복 실행 검증 방법입니다.
실행 경로를 먼저 배포하세요
조립스페이스 크론은 중앙 스케줄러가 배포된 Worker의 GET·POST 경로를 호출합니다. scheduled() 함수나 로컬 타이머를 작성하는 것만으로 프로젝트 스케줄이 등록되지 않습니다. 아래는 만료된 앱 세션을 최대 100개씩 정리하는 예제입니다.
import { Hono } from 'hono';
import type { AppEnv } from '../types';
export const jobs = new Hono<AppEnv>();
jobs.post('/cleanup-sessions', async (c) => {
// 스케줄러는 비공개 Dispatch 호출로 이 URL을 전달합니다.
// X-JoripSpace-Cron-ID 같은 공개 헤더만으로 허용하면 안 됩니다.
if (new URL(c.req.url).hostname !== 'joripspace-cron.internal')
return c.json({ error: 'scheduler_required' }, 403);
const result = await c.env.DB.prepare(
'DELETE FROM app_sessions WHERE session_hash IN (' +
'SELECT session_hash FROM app_sessions WHERE expires_at<=? ORDER BY expires_at LIMIT 100)'
).bind(Date.now()).run();
// 반복 실행해도 안전하며, 남은 항목은 다음 스케줄에서 처리합니다.
return c.json({ ok: true, deleted: result.meta.changes });
});import { jobs } from './routes/jobs';
app.route('/jobs', jobs);필요한 app_sessions 테이블과 만료 인덱스는 Hono 예제에 있습니다. 비공개 호출의 내부 URL을 확인하고, 공개 요청이 보낸 크론 헤더만 믿지 않습니다. 일반 도메인으로 위 경로를 POST하면 403이어야 합니다.
중복 확인 후 UTC 스케줄 등록
joripspace crons --project PROJECT
joripspace cron create --project PROJECT --schedule "*/5 * * * *" --path /jobs/cleanup-sessions --method POST --name "만료 세션 정리"5필드 형식은 분·시·일·월·요일이며 UTC 기준입니다. 같은 목적의 스케줄이 이미 있으면 중복 생성하지 마세요.
| 실행 의도 | UTC 표현식 |
|---|---|
| 5분마다 | */5 * * * * |
| 매일 한국 시간 오전 9시 | 0 0 * * * |
| 매일 한국 시간 자정 | 0 15 * * * · UTC 전날 15시 |
다른 지역은 서머타임을 포함한 시간대 변환을 확인하세요.
등록 후 즉시 실행과 상태 확인
joripspace cron run --project PROJECT --cron-id CRON_ID
joripspace crons --project PROJECT
joripspace events --project PROJECT --event-type error생성 응답의 실제 CRON_ID를 사용합니다. last_status와 next_run_at을 확인하고, DB 변경이 의도대로 일어났는지 확인하세요. 등록 성공만으로 실행 성공을 보고하지 않습니다.
joripspace cron delete --project PROJECT --cron-id CRON_ID --yes반복·지연·실패에 대비하세요
같은 작업이 두 번 호출되거나 응답을 받지 못해도 데이터가 망가지지 않도록 만드세요. 정리는 조건부 DELETE, 정산·발송은 고유 작업 ID와 DB 상태 전이로 중복 실행을 방지합니다. 외부 API 작업은 outbox에 기록하고 next_attempt_at 인덱스로 처리 대상을 제한합니다.
한 번에 전체 데이터를 읽지 말고 제한된 개수와 커서로 나누세요. 중요한 예약 작업은 마지막 성공 시각과 지연을 감시합니다. 등록된 시각에 정확히 한 번 성공한다는 전제로 업무를 설계하지 마세요.