Skip to main content

A lightweight, thread-safe, and zero-dependency concurrent task scheduling engine for Python.

Project description

Robust Scheduler

Tests Python Version Linter: Ruff License: MIT

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.

  1. Clone the repository:

    git clone [https://github.com/ckalandk/scheduler.git](https://github.com/ckalandk/scheduler.git)
    cd scheduler
    
  2. 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:

  1. Task: A lightweight container that holds the target function, (stored internally in a functools.partial), and its timing requirements (timeout, repeat).

  2. ThreadPool: A custom-built worker pool utilizing queue.Queue. It bypasses the heavy machinery of concurrent.futures.ThreadPoolExecutor for fire-and-forget tasks, ensuring maximum throughput.

  3. Scheduler: The orchestrator. It uses a queue.PriorityQueue and a threading.Condition to precisely calculate time deltas and hand off tasks to the ThreadPool at 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

schedcore-0.1.0.tar.gz (5.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

schedcore-0.1.0-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

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

Hashes for schedcore-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1c175159eb2023deed2b31151cc939cf643729e5dbaead93751d90de22550afc
MD5 9cf8c98ba4e44448c699f1cb638b2203
BLAKE2b-256 d94344810e7f1ec5186f40da0ae7d90583da72a131f2f75e34286a57fb9d9396

See more details on using hashes here.

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

Hashes for schedcore-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f9d79aa215064dcf72acdbc757f28435a0d746f9535880bb82a187730c2b7bbb
MD5 da7df5b82271ef2a8b8471ffdc5e5762
BLAKE2b-256 ad5cbc2b16114924478ad2a10650cc341326552a0f2e073684a81da6e0a2c0a7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page