A lightweight, thread-safe, and zero-dependency concurrent task scheduling engine for Python.
Project description
Robust Scheduler
A lightweight, thread-safe, and zero-dependency concurrent task scheduling engine for Python.
scheduler allows you to schedule tasks to execute in the future, handle recurring tasks, and process them concurrently using a custom-built, lightweight thread pool—all without the overhead of heavy third-party libraries.
🚀 Features
- Zero Dependencies: Built entirely using Python's standard library (
threading,queue,time). - Custom Execution Engine: Uses a custom ThreadPool designed for absolute bare-metal performance.
- Thread-Safe Architecture: Protected by condition variables and thread-safe queues to prevent race conditions and spurious wakeups.
- Configurable error handling: uses callback function for error handling which can be supplied via
set_error_handler() - Graceful Shutdown: Implements the "Poison Pill" pattern to ensure all background OS threads terminate cleanly without leaking memory.
- Modern Python: Fully type-hinted and compatible with Python 3.10+.
🛠️ Installation
This project uses uv, you can easily set it up for local development.
-
Clone the repository:
git clone [https://github.com/ckalandk/scheduler.git](https://github.com/ckalandk/scheduler.git) cd scheduler
-
Install the package in editable mode using uv:
uv sync
📖 Quick Start
The following example, demonstrate how to start a scheduler, submit tasks and gracefully shut it down
import time
from scheduler import Scheduler, Task
# 1. Define your tasks
def greet(name: str):
print(f"[{time.strftime('%X')}] Hello, {name}!")
def recurring_ping():
print(f"[{time.strftime('%X')}] Ping...")
def raise_error():
raise ValuerError("Task raised and exception")
def error_handler(exception, task):
print(f"Task: {task} didn't execute du to an exception: {exception})
# 2. Initialize the Scheduler (automatically sizes the ThreadPool based on CPU cores)
scheduler = Scheduler(workers=4)
scheduler.set_error_handler(error_hander)
scheduler.start()
print(f"[{time.strftime('%X')}] Scheduler started.")
# 3. Schedule tasks
# Runs once, 2 seconds from now
task_one = Task(timeout=2, repeat=False, func=greet, name="Alice")
scheduler.schedule(task_one)
# Runs repeatedly, every 1.5 seconds
task_two = Task(timeout=1.5, repeat=True, func=recurring_ping)
scheduler.schedule(task_two)
# 4. Keep the main thread alive to watch the background threads work
try:
time.sleep(6)
except KeyboardInterrupt:
pass
finally:
# 5. Cleanly shut down all background threads
print("Shutting down gracefully...")
scheduler.request_stop()
🧠 Architecture Overview
This library is split into three core components:
-
Task: A lightweight container that holds the target function, (stored internally in afunctools.partial), and its timing requirements (timeout,repeat). -
ThreadPool: A custom-built worker pool utilizingqueue.Queue. It bypasses the heavy machinery ofconcurrent.futures.ThreadPoolExecutorfor fire-and-forget tasks, ensuring maximum throughput. -
Scheduler: The orchestrator. It uses aqueue.PriorityQueueand athreading.Conditionto precisely calculate time deltas and hand off tasks to theThreadPoolat the exact right microsecond.
🧪 Running Tests
To run the test suite:
uv run pytest -v
📄 License
MIT License. See LICENSE for more information.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file schedcore-0.1.0.tar.gz.
File metadata
- Download URL: schedcore-0.1.0.tar.gz
- Upload date:
- Size: 5.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c175159eb2023deed2b31151cc939cf643729e5dbaead93751d90de22550afc
|
|
| MD5 |
9cf8c98ba4e44448c699f1cb638b2203
|
|
| BLAKE2b-256 |
d94344810e7f1ec5186f40da0ae7d90583da72a131f2f75e34286a57fb9d9396
|
File details
Details for the file schedcore-0.1.0-py3-none-any.whl.
File metadata
- Download URL: schedcore-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9d79aa215064dcf72acdbc757f28435a0d746f9535880bb82a187730c2b7bbb
|
|
| MD5 |
da7df5b82271ef2a8b8471ffdc5e5762
|
|
| BLAKE2b-256 |
ad5cbc2b16114924478ad2a10650cc341326552a0f2e073684a81da6e0a2c0a7
|