Skip to main content

安全的资源感知任务调度器,永远不会把你的机器跑崩

Project description

safesched

Python License PyPI

安全的资源感知任务调度器 — 自动监控 CPU/内存/磁盘 IO/GPU 显存,过载时暂停调度,永远不会把你的机器跑崩。

✨ 主要特性

  • 🔍 自动资源监控:实时监控 CPU、内存、磁盘 IO 和 GPU 显存
  • 🛡️ 智能过载保护:系统过载时自动暂停,避免宕机
  • 🎯 GPU 自动选择:自动检测并选择最空闲的 GPU
  • ♻️ 任务重试:失败任务自动重试,可配置重试次数
  • 📊 并发管理:灵活配置并发任务数和超时时间

📦 安装

推荐方式(使用 pipx,全局隔离安装)

pipx install safesched

或使用 pip(在虚拟环境中)

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install safesched

从源码安装(开发者)

git clone https://github.com/Misaka14766/safesched.git
cd safesched
pip install -e .

🚀 快速开始

批量调度任务(从 stdin)

cat tasks.txt | safesched python process.py {}

其中 tasks.txt 每行一个参数,{} 作为占位符被替换。

运行单个命令

自动选择最空闲的 GPU 并执行:

safesched run python train_model.py

指定 GPU 并配置并发

cat tasks.txt | safesched -g 0,1 -j 8 -t 3600 python process.py {}

参数说明:

  • -g 0,1:指定 GPU 列表(默认自动检测)
  • -j 8:最大并发任务数(默认 8×GPU 数 或 CPU 核心数 / 2)
  • -t 3600:单个任务超时时间(秒,默认 1 小时)
  • -r 3:失败重试次数(默认 2 次)
  • -v:详细日志输出

更多例子

处理 10000 个视频文件,自动检测 GPU,并发 4 个任务,每个任务超时 30 分钟:

ls *.mp4 | safesched -j 4 -t 1800 python encode.py {}

使用 CPU 模式处理任务(无 GPU):

cat tasks.txt | safesched python lightweight_task.py {}

🧪 开发与测试

安装开发依赖

git clone https://github.com/Misaka14766/safesched.git
cd safesched
pip install -e ".[dev]"

运行测试

# 运行所有测试
pytest -v

# 运行特定测试模块
pytest tests/test_monitor.py -v
pytest tests/test_cli.py -v

# 显示覆盖率(需要 pytest-cov)
pytest --cov=safesched tests/

🔄 CI/CD 工作流

项目使用 GitHub Actions 自动进行持续集成和发布:

工作流 触发条件 功能
Tests Push 到 maindevelop,PR 在 Ubuntu/Windows/macOS 上测试 Python 3.8~3.12
Publish 创建 Release 或推送 v* tag 自动构建并发布到 PyPI

发布新版本

  1. 更新版本号

    # 编辑 pyproject.toml,修改 version = "x.y.z"
    
  2. 提交并推送

    git add pyproject.toml
    git commit -m "Release v0.2.0"
    git push origin main
    
  3. 创建 Release(推荐)或打 tag

    # 方式 1: 在 GitHub 上创建 Release(更正式)
    
    # 方式 2: 使用 git tag
    git tag v0.2.0
    git push origin v0.2.0
    
  4. GitHub Actions 自动处理

    • 构建分发包(.whl 和 .tar.gz)
    • 运行 twine 检查元数据
    • 上传到 PyPI

⚠️ 注意:首次发布需要在 GitHub 仓库 Settings 中配置 PYPI_API_TOKEN secret,获取方式:

  1. https://pypi.org 注册账号
  2. 创建 API Token(Account Settings → API tokens)
  3. 在 GitHub 仓库 Settings → Secrets → New repository secret,添加 PYPI_API_TOKEN

📝 许可证

MIT License - 详见 LICENSE 文件

👤 作者

💬 反馈与贡献

欢迎提交 Issue 和 Pull Request!如有任何问题或建议,请通过以下方式联系:


Made with ❤️ by Misaka14766

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

safesched-0.1.0.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

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

safesched-0.1.0-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file safesched-0.1.0.tar.gz.

File metadata

  • Download URL: safesched-0.1.0.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for safesched-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bc5c7733f4b10f8a271c114d3bb7aaedcf7f61b4ba659b4f4224533c8539c0c0
MD5 cca90abe963544b827bde16c69fcdd1e
BLAKE2b-256 5d17f503759b16c0b5c77e57eb8b2d7b2cdf8eb27d07b93f53edf717d50d0473

See more details on using hashes here.

File details

Details for the file safesched-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: safesched-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for safesched-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8fffadb6b10e4c1532eefda5acc837ef4eca3dbcf4f72930025c095b8ab8c163
MD5 94bf9b0a0619fe21f7dc60920546d899
BLAKE2b-256 bb92a1e426bca281c7a4b054dfc2fe83b3616dbb9d93c810a0479e6285be0000

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