Author: Kyle
Email: kyle@hacking-linux.com
Version: 0.0.1
JobsManager is a lightweight, database-driven job scheduling service built on top of APScheduler and MySQL.
It is designed as a long-running service and focuses on:
- Persistent job scheduling
- Explicit, database-controlled reloads
- Clear separation between job management and scheduler runtime
- Predictable behavior suitable for production environments
βββββββββββββββββββββββ
β bin/JobsManager.py β
β Service entry point β
βββββββββββ¬ββββββββββββ
β
βββββββββββΌββββββββββββ
β JobsManagerService β
β Scheduler runtime β
β - APScheduler β
β - reload logic β
β - signal handling β
βββββββββββ¬ββββββββββββ
β
βββββββββββΌββββββββββββ
β Task β
β Job management API β
β - add / update β
β - remove / list β
βββββββββββ¬ββββββββββββ
β
βββββββββββΌββββββββββββ
β Job β
β Job definition β
β - cron schedule β
β - shell command β
βββββββββββββββββββββββ
JobsManager/
βββ bin/
β βββ JobsManager.py
β βββ TaskSample.py
βββ etc/
β βββ global.json
βββ lib/
β βββ Config.py
β βββ Job.py
β βββ JobsManagerService.py
β βββ Log.py
β βββ MySQL.py
β βββ Task.py
βββ log/
β βββ jobsmanager.log
βββ systemd/
β βββ jobsmanager.service
βββ requirements.txt
βββ pyproject.toml
βββ README.md
lib/JobsManagerService.py
The scheduler runtime service responsible for:
- Initializing APScheduler with a MySQL-backed job store
- Managing scheduler lifecycle (start / stop)
- Detecting database changes
- Reloading scheduler state safely
- Handling graceful shutdown via system signals
lib/Task.py
A lightweight wrapper around APScheduler providing job management APIs:
- Add, update, remove scheduled jobs
- Translate
Jobdefinitions into cron triggers - Execute shell commands with timeout control
lib/Job.py
A pure data model describing a scheduled job:
- Job identifier
- Shell command
- Cron-style schedule fields
- Execution timeout
JobsManager uses MySQL as the single source of truth for job persistence and scheduler reload coordination.
Reloads are explicit, rate-limited, and controlled by database state.
βββββββββββββββββββββββββββββ
β JobsManager.py β
β Service entry point β
ββββββββββββββββ¬βββββββββββββ
β
ββββββββββββββββΌβββββββββββββ
β JobsManagerService β
β runtime loop β
β - poll DB β
β - reload if needed β
ββββββββββββββββ¬βββββββββββββ
β
check β
β
ββββββββββββββββΌβββββββββββββ
β jm_update_info β
β reload marker table β
β - updated = 0 ? β
ββββββββββββββββ¬βββββββββββββ
β
full β
reload β
β
ββββββββββββββββΌβββββββββββββ
β APScheduler β
β SQLAlchemyJobStore β
β - load jobs from MySQL β
βββββββββββββββββββββββββββββ
- Job changes do not directly reload the scheduler
- A marker row is inserted into
jm_update_infowithupdated = 0 - The scheduler polls for pending markers
- Reload is triggered only when pending markers exist
- Reloads are serialized using a lock
- Scheduler state is rebuilt from database state
JobsManager supports file-based and database-backed logging.
βββββββββββββββββββββββββββββ
β Application / Scheduler β
β - lifecycle events β
β - reload operations β
β - job execution β
ββββββββββββββββ¬βββββββββββββ
β
ββββββββββββββββΌβββββββββββββ
β Logging subsystem β
β - file handler β
β - MySQL handler β
ββββββββββββββββ¬βββββββββββββ
β
ββββββββββββββββΌβββββββββββββ
β jm_syslog β
β persistent logs β
βββββββββββββββββββββββββββββ
This section describes the logical schema (ER-style) of JobsManager tables. DDL definitions are intentionally omitted from this README.
ββββββββββββββββββββββββββββββββ
β jm_syslog β
ββββββββββββββββββββββββββββββββ€
β id (PK) β
β created_at β
β level β
β logger_name β
β message β
ββββββββββββββββββββββββββββββββ€
β Purpose: β
β - Persistent system logging β
β - Reload and runtime logs β
β - Execution error logs β
ββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββ
β jm_update_info β
ββββββββββββββββββββββββββββββββ€
β id (PK) β
β updated β
β insert_time β
β update_time β
β jobs_before_update β
β jobs_after_update β
ββββββββββββββββββββββββββββββββ€
β Purpose: β
β - Signal scheduler reloads β
β - Track change context β
ββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββ
β Job / Task Management β
β - add / update / remove β
ββββββββββββββββ¬βββββββββββββ
β
insert β updated = 0
β
ββββββββββββββββΌβββββββββββββ
β jm_update_info β
β reload marker β
ββββββββββββββββ¬βββββββββββββ
β
poll β
β
ββββββββββββββββΌβββββββββββββ
β JobsManagerService β
β - detect updates β
β - trigger reload β
ββββββββββββββββ¬βββββββββββββ
β
log β
β
ββββββββββββββββΌβββββββββββββ
β jm_syslog β
β persistent logs β
βββββββββββββββββββββββββββββ
Jobs are defined using the Job data model.
Job(
id: str,
command: str,
second: str = "*",
minute: str = "*",
hour: str = "*",
day: str = "*",
month: str = "*",
day_of_week: str = "*",
timeout: int = 60
)id: Unique job identifiercommand: Shell command executed usingsubprocess.run(..., shell=True)
second,minute,hour,day,month,day_of_week: Cron-style schedule fields (default"*")timeout: Max execution time in seconds (default60)
job = Job(
id="job_echo",
command='echo "hello world"',
minute="*/5",
timeout=10
)python bin/JobsManager.pycp systemd/jobsmanager.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable jobsmanager
systemctl start jobsmanagerbin/TaskSample.py demonstrates job operations such as list/add/update/remove.
- Database is the source of truth
- Reloads are explicit and controlled
- Scheduler state is always rebuildable
- Observability is a first-class concern
- Designed for long-running supervised services
MIT License