Citrine - scheduled jobs for your Elixir app with cron syntax

I’d like to announce a new library I wrote recently for a project I’ve been working on. The library is called Citrine, it’s for managing and running scheduled jobs on an Erlang cluster as part of an existing application.

Summary: With Citrine you define a job, schedule it using cron syntax, and the library manages execution globally across the cluster to keep jobs running continuously. It’s designed to be used in stateless application environments such as Kubernetes.

# Create a job
job = %Citrine.Job{
  id: "my_job_id",
  schedule: "* * * * * *", # Run every second
  task: job_task,
  extended_syntax: true # Use extended cron syntax
}
# Start or update a job
MyApp.Scheduler.put_job(job)
# Terminate and delete a job
MyApp.Scheduler.delete_job(job)

Why I made this: I spent quite a bit of time looking into some of the existing libraries that existed, and none of them did exactly when I wanted, so I decided to build my own. It uses mnesia for state management, and mostly relies on Erlang primitives for everything. Thus, there are very few external dependencies (currently it only uses the crontab library, which itself has almost zero dependencies).

Some other thoughts: I followed convention over configuration with this library. As such, there aren’t many options to change, and the API interface itself really only has 3 function (put a job, delete a job, and list jobs).

Docs: https://hexdocs.pm/citrine/readme.html

8 Likes

What are main differences between this and Quantum?

1 Like

Initially I was using Quantum, but I found that the global mode it came with was not working properly. The reasons are documented in this GitHub issue. To be fair, it looks like there’s been a lot of progress since I last used it.

I also looked into using the Horde CRDT library instead of mnesia, but I found it to be too buggy and unreliable. I spent a few days working on resolving the bugs in Horde (you can see my fork here if you want) but it was taking up too much time and I needed to focus on other things.

I ended up just writing a really small library to do exactly what I needed, and I decided to clean it up and open source it for anyone to use.

4 Likes