Clockwork

Package Version Hex Docs

A robust cron-like job scheduling library for Gleam, designed for reliability and ease of use.

Features

Installation

gleam add clockwork

Quick Start

import clockwork
import clockwork/schedule
import gleam/erlang/process
import gleam/io
import gleam/time/duration

pub fn main() {
  // Create a cron schedule that runs every minute
  let assert Ok(cron) = "* * * * *" |> clockwork.from_string

  // Define a job function
  let job = fn() { 
    io.println("This job runs every minute!")
    Nil
  }
  
  // Create and configure a scheduler
  let scheduler = schedule.new("minutely-job", cron, job)
    |> schedule.with_logging()
    |> schedule.with_telemetry()
  
  // Start the scheduler
  let assert Ok(running_schedule) = schedule.start(scheduler)
  
  // Keep the process running
  process.sleep_forever()
}

Cron Expressions

Clockwork supports standard cron expressions with five fields:

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
│ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) (0 is Sunday)
│ │ │ │ │
* * * * *

Common patterns:

You can also build cron expressions programmatically:

// Create a cron schedule using the builder pattern
let cron = clockwork.default()
  |> clockwork.with_minute(clockwork.every(15))
  |> clockwork.with_hour(clockwork.exactly(at: 0))
  |> clockwork.with_day(clockwork.list([
    clockwork.exactly(at: 1), 
    clockwork.exactly(at: 15)
  ]))
  |> clockwork.with_month(clockwork.ranging(from: 5, to: 10))
  |> clockwork.with_weekday(clockwork.ranging_every(2, from: 2, to: 6))

Scheduling Jobs

The schedule module provides a builder-style API for configuring and running jobs:

// Create a new scheduler with a unique ID, cron expression and job function
let scheduler = schedule.new("job-id", cron_expression, job_function)

// Enable optional features using builder methods
let configured_scheduler = scheduler
  |> schedule.with_logging()        // Enable logging
  |> schedule.with_telemetry()      // Enable OpenTelemetry integration
  |> schedule.with_time_offset(     // Run in US Eastern Time
       duration.hours(-5)
     )

// Start the scheduler
let result = schedule.start(configured_scheduler)

// Later, stop a running job
case result {
  Ok(running_job) -> schedule.stop(running_job)
  Error(_) -> io.println("Failed to start job")
}

Timezone Support

Jobs can be configured to run in specific timezones by setting a time offset:

// Run jobs in local timezone
let local_job = schedule.new("local-job", cron, job)
  |> schedule.with_time_offset(calendar.local_offset())

// Run jobs in a specific timezone (e.g., UTC+2)
let berlin_job = schedule.new("berlin-job", cron, job)
  |> schedule.with_time_offset(duration.hours(2))

Telemetry Integration

Clockwork integrates with OpenTelemetry to provide observability for your scheduled jobs:

// Enable telemetry for a job
let observable_job = schedule.new("tracked-job", cron, job)
  |> schedule.with_telemetry()

This will create spans for each job execution with detailed information about the job’s timing and execution context.

Practical Example: Daily Report Generator

import clockwork
import clockwork/schedule
import gleam/erlang/process
import gleam/io
import gleam/time/calendar
import gleam/time/duration

pub fn main() {
  // Create a cron schedule for midnight every day
  let assert Ok(cron) = "0 0 * * *" |> clockwork.from_string
  
  // Define the report generation job
  let generate_daily_report = fn() {
    io.println("Generating daily report...")
    // Report generation code would go here
    io.println("Daily report completed!")
    Nil
  }
  
  // Create and configure the scheduler
  let scheduler = schedule.new(
    "daily-report-generator", 
    cron,
    generate_daily_report
  )
  |> schedule.with_logging()
  |> schedule.with_time_offset(calendar.local_offset())
  
  // Start the scheduler
  let assert Ok(running_schedule) = schedule.start(scheduler)
  
  io.println("Daily report scheduler started!")
  process.sleep_forever()
}

Documentation

For detailed documentation, visit HexDocs.

Development

gleam run   # Run the project
gleam test  # Run the tests
gleam format # Format the code

License

Clockwork is licensed under the MIT License.

Search Document