§ reference

scheduled_tasks

The optional db-scheduler table used by distributed jobs and local event handlers.

scheduled_tasks is optional. You only need it when you use distributed jobs directly, or when you use a module that depends on distributed jobs, such as the local event handler. EventFanoutJob and EventHandlingJob are distributed jobs, so local event handling needs scheduled_tasks.

scheduled_tasks is owned by db-scheduler. Ekbatan’s JobRegistry is a small facade over db-scheduler, but it deliberately does not wrap this table in an Ekbatan model. Keep the db-scheduler schema verbatim for your dialect.

Required when: only when you use ekbatan-distributed-jobs, or any module built on it such as ekbatan-local-event-handler.

Writer: db-scheduler, through Ekbatan’s JobRegistry facade.

Row model: no Ekbatan model. db-scheduler owns this table.

DDL

src/main/resources/db/migration/ V0002__scheduled_tasks.sql
sql
1 -- db-scheduler's required schema for PostgreSQL.
2 -- This is db-scheduler's own table, so Ekbatan intentionally steps
3 -- off the always-TIMESTAMP rule here.
4 create table scheduled_tasks (
5 task_name text not null,
6 task_instance text not null,
7 task_data bytea,
8 execution_time timestamp with time zone not null,
9 picked BOOLEAN not null,
10 picked_by text,
11 last_success timestamp with time zone,
12 last_failure timestamp with time zone,
13 consecutive_failures INT,
14 last_heartbeat timestamp with time zone,
15 version BIGINT not null,
16 priority SMALLINT,
17 PRIMARY KEY (task_name, task_instance)
18 );
19
20 CREATE INDEX execution_time_idx ON scheduled_tasks (execution_time);
21 CREATE INDEX last_heartbeat_idx ON scheduled_tasks (last_heartbeat);
22 CREATE INDEX priority_execution_time_idx ON scheduled_tasks (priority desc, execution_time asc);
src/main/resources/db/migration/ V0002__scheduled_tasks.sql
sql
1 -- db-scheduler's required schema for MariaDB / MySQL.
2 -- This is db-scheduler's own table, so Ekbatan intentionally follows
3 -- db-scheduler's schema verbatim.
4 create table scheduled_tasks (
5 task_name VARCHAR(100) NOT NULL,
6 task_instance VARCHAR(100) NOT NULL,
7 task_data BLOB,
8 execution_time TIMESTAMP(6) NOT NULL,
9 picked BOOLEAN NOT NULL,
10 picked_by VARCHAR(50),
11 last_success TIMESTAMP(6) NULL,
12 last_failure TIMESTAMP(6) NULL,
13 consecutive_failures INT,
14 last_heartbeat TIMESTAMP(6) NULL,
15 version BIGINT NOT NULL,
16 priority SMALLINT,
17 PRIMARY KEY (task_name, task_instance),
18 INDEX execution_time_idx (execution_time),
19 INDEX last_heartbeat_idx (last_heartbeat),
20 INDEX priority_execution_time_idx (priority, execution_time)
21 );
src/main/resources/db/migration/ V0002__scheduled_tasks.sql
sql
1 -- db-scheduler's required schema for MySQL.
2 -- This is db-scheduler's own table, so Ekbatan intentionally follows
3 -- db-scheduler's schema verbatim.
4 create table scheduled_tasks (
5 task_name VARCHAR(100) NOT NULL,
6 task_instance VARCHAR(100) NOT NULL,
7 task_data BLOB,
8 execution_time TIMESTAMP(6) NOT NULL,
9 picked BOOLEAN NOT NULL,
10 picked_by VARCHAR(50),
11 last_success TIMESTAMP(6) NULL,
12 last_failure TIMESTAMP(6) NULL,
13 consecutive_failures INT,
14 last_heartbeat TIMESTAMP(6) NULL,
15 version BIGINT NOT NULL,
16 priority SMALLINT,
17 PRIMARY KEY (task_name, task_instance),
18 INDEX execution_time_idx (execution_time),
19 INDEX last_heartbeat_idx (last_heartbeat),
20 INDEX priority_execution_time_idx (priority, execution_time)
21 );

Columns

ColumnPostgreSQL typeMySQL/MariaDB typeMeaning
task_nametextVARCHAR(100)Cluster-wide task name. For Ekbatan jobs this comes from DistributedJob.name().
task_instancetextVARCHAR(100)db-scheduler task instance id. Together with task_name, this is the primary key.
task_databyteaBLOBSerialized db-scheduler task payload. Ekbatan’s recurring DistributedJob facade does not expose this as application data.
execution_timetimestamp with time zoneTIMESTAMP(6)Next scheduled execution time. db-scheduler queries and orders by this.
pickedBOOLEANBOOLEANWhether a scheduler instance has claimed this row for execution.
picked_bytextVARCHAR(50)Identifier of the scheduler instance that claimed the row. NULL when not picked.
last_successtimestamp with time zoneTIMESTAMP(6)Last successful completion time, if any.
last_failuretimestamp with time zoneTIMESTAMP(6)Last failed completion time, if any.
consecutive_failuresINTINTNumber of consecutive failures recorded by db-scheduler.
last_heartbeattimestamp with time zoneTIMESTAMP(6)Last heartbeat from the scheduler instance that owns the execution. Used to detect dead executions.
versionBIGINTBIGINTdb-scheduler’s optimistic concurrency field for claims and updates.
prioritySMALLINTSMALLINTOptional scheduler priority.

Indexes

IndexPurpose
Primary key on (task_name, task_instance)Identifies a scheduled task instance.
execution_time_idx on (execution_time)Lets scheduler polling find due rows.
last_heartbeat_idx on (last_heartbeat)Lets db-scheduler detect stale picked executions.
priority_execution_time_idx on priority + execution timeLets db-scheduler poll by priority and due time. PostgreSQL examples use (priority desc, execution_time asc); MySQL/MariaDB examples use (priority, execution_time) following db-scheduler’s dialect schema.

See also