January 25, 2022
I just built a feature into War Room that allows people to define recurring tasks, which are re-added to their to-do list every day. For example, a task could be automatically added to your to-do list at midnight on weekdays.
War Roomâs interface for creating recurring tasks.
Building a recurring tasks feature is an interesting challenge. I wanted to explain, in broad strokes, the solution I chose:
My first instinct would have been to save this data directly into the database: the task, its repeating time, and which days are enabled.
Then, I could run a piece of code every hour that pulls out all the tasks that match the current hour and day, and then add those to peopleâs to-do lists.
However, this solution presents a couple problems:
Firstly, I decided to store the taskâs schedule in whatâs called cron format. Itâs a clever way of storing schedule information using five phrases with spaces in between:
* * * * *
- - - - -
| | | | |
| | | | |
| | | | +----- day of week, 0 (Sun) - 6 (Sat)
| | | +---------- month, 1 - 12
| | +--------------- day of month, 1 - 31
| +-------------------- hour, 0 - 23
+------------------------- min, 0 - 59
Does that kinda make sense?
I store the recurring taskâs options as a cron statement, so âevery weekday at 4amâ is stored in War Roomâs database as:
0 4 * * 1,2,3,4,5
Then, when you first create or edit a recurring task, I calculate the ânext execution timeâ. I parse this cron statement and figure out when the next time is that this statement comes true â the next time that this task should be added to your to-do list.
Then, I execute a bit of code every hour that grabs all the recurring tasks whose ânext execution timeâ is in the past. Ideally, thatâs in the recent past (for example, the code executes at 3:01am and weâre grabbing tasks that were supposed to be added at 3:00am), but this will also catch the problem where the server goes offline. A task that shouldâve been added at 3am will be caught when the server comes back online at 8am, because its execution time (3am) is still in the past.
After adding the task to the correct userâs to-do list, I re-calculate the next execution time. This way, it wonât be added again next hour, since the next execution time is pushed into the future.
Thereâs some other fun challenges about building this feature:
$date
in a recurring task it can be replaced with the correct current date depending on which time zone youâre in.