문서 / 크론과 정기 실행
크론과 정기 실행
UTC 스케줄 등록, 내부 호출 보호와 반복 실행 검증 방법입니다.
실행 경로를 먼저 배포하세요
조립스페이스의 크론은 지정한 일정에 따라 배포된 Worker의 GET·POST 경로를 호출합니다. 실행할 경로를 먼저 배포한 뒤 CLI로 스케줄을 등록합니다. Worker의 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 인덱스로 처리 대상을 제한합니다.
한 번에 전체 데이터를 읽지 말고 제한된 개수와 커서로 나누세요. 중요한 예약 작업은 마지막 성공 시각과 지연을 감시합니다. 실행이 지연되거나 실패했을 때 다시 처리할 수 있도록 작업 상태를 기록해 두는 것이 좋습니다.