---
title: Cron
description: Job scheduling with simple and distributed modes, retries, and admin API
---

## Overview

`github.com/xraph/forge/extensions/cron` provides a cron job scheduler for Forge applications.
It supports simple (single-node) and distributed (leader-elected) scheduling modes with job
registration, execution history, retries with backoff, and an admin REST API with optional web UI.

## What It Registers

| Service | DI Key | Type |
|---|---|---|
| Job registry | `cron.registry` | `*JobRegistry` |
| Job executor | `cron.executor` | `*Executor` |
| Scheduler | `cron.scheduler` | `Scheduler` |
| Storage | `cron.storage` | `Storage` |

All services are managed by Vessel. The scheduler starts during the extension's `Start()` phase.

## Dependencies

- **Optional:** `database` extension -- required when `Storage` is set to `"database"`.
- **Optional:** `consensus` extension -- required in `"distributed"` mode with `LeaderElection` enabled.

## Quick Start

```go
package main

import (
    "context"
    "fmt"

    "github.com/xraph/forge"
    "github.com/xraph/forge/extensions/cron"
)

func main() {
    app := forge.NewApp(forge.AppConfig{Name: "my-app", Version: "1.0.0"})

    ext := cron.NewExtension(
        cron.WithMode("simple"),
        cron.WithStorage("memory"),
        cron.WithMaxConcurrentJobs(10),
        cron.WithEnableAPI(true),
    )
    app.RegisterExtension(ext)

    // Register job handlers before starting
    registry := ext.GetRegistry()

    registry.Register("send-reports", func(ctx context.Context, job *cron.Job) error {
        fmt.Println("Generating and sending reports...")
        return nil
    })

    registry.Register("cleanup-temp", func(ctx context.Context, job *cron.Job) error {
        fmt.Println("Cleaning up temporary files...")
        return nil
    })

    // Create jobs
    ctx := context.Background()
    app.Start(ctx)
    defer app.Stop(ctx)

    ext.CreateJob(ctx, &cron.Job{
        Name:        "Daily Reports",
        Schedule:    "0 9 * * *",  // every day at 9 AM
        HandlerName: "send-reports",
        Enabled:     true,
        Timezone:    "America/New_York",
        MaxRetries:  3,
        Timeout:     5 * time.Minute,
    })

    ext.CreateJob(ctx, &cron.Job{
        Name:        "Hourly Cleanup",
        Schedule:    "0 * * * *",  // every hour
        HandlerName: "cleanup-temp",
        Enabled:     true,
    })
}
```

## Job Management at Runtime

```go
// Trigger a job manually (outside its schedule)
ext.TriggerJob(ctx, jobID)

// Update a job
ext.UpdateJob(ctx, jobID, &cron.Job{
    Schedule: "*/30 * * * *",  // change to every 30 minutes
    Enabled:  true,
})

// Delete a job
ext.DeleteJob(ctx, jobID)

// Get execution stats
stats, _ := ext.GetStats(ctx)
fmt.Printf("Total jobs: %d, Running: %d\n", stats.TotalJobs, stats.RunningJobs)
```

## Handler Middleware

```go
// Add middleware to handlers
registry.RegisterWithMiddleware("critical-job", myHandler,
    cron.CreateLoggingMiddleware(logger),
    cron.CreateTimeoutMiddleware(5*time.Minute),
    cron.CreatePanicRecoveryMiddleware(logger),
)
```

## Key Concepts

- **Simple mode** -- single-node scheduler using standard cron expressions.
- **Distributed mode** -- uses the consensus extension for leader election. Only the leader executes jobs.
- **Job registry** -- register handlers by name. Jobs reference handlers by name.
- **Executor** -- runs handlers with concurrency limits, timeout enforcement, and retry logic.
- **Storage** -- persist job definitions and history in memory or database backends.
- **Admin API** -- REST API at `/api/cron` for managing jobs.

## Detailed Pages

<Cards>
<Card title="Features" href="/docs/forge/extensions/cron/features">
Scheduling, execution, retries, distributed mode, and admin capabilities.
</Card>
<Card title="Configuration" href="/docs/forge/extensions/cron/configuration">
Config reference, YAML example, and programmatic options.
</Card>
<Card title="Functions" href="/docs/forge/extensions/cron/functions">
Public API grouped by purpose with descriptions.
</Card>
</Cards>
