Skip to content

FA Scheduling

Arian Omrani edited this page Oct 11, 2026 · 6 revisions

زمان‌بندی

زبان: English · فارسی

pulsecheck یک‌بار اجرا می‌شود و تمام می‌شود. باید چیز دیگری هر چند دقیقه یک‌بار آن را راه بیندازد. یکی از روش‌های زیر را انتخاب کنید.

GitHub Actions

سریع‌ترین راه، قالب حداقلی arian24b/pulsecheck-template است. فقط چهار فایل دارد: pulsecheck.yml، یک workflow، یک README کوتاه و .gitignore. workflow بسته‌ی pulsecheckcli را از PyPI نصب می‌کند، پس هیچ کد منبعی وارد مخزن شما نمی‌شود.

  1. روی Use this template ← Create a new repository بزنید و گزینه‌ی Private را انتخاب کنید، چون pulsecheck.yml نام سرورهای شما را در خود دارد.
  2. pulsecheck.yml را ویرایش کنید: سایت‌هایتان را زیر sites: بگذارید و توکن‌ها را به شکل ${VAR} نگه دارید.
  3. هر متغیر را در Settings ← Secrets and variables ← Actions به‌عنوان secret اضافه کنید و اسمش را زیر env: در .github/workflows/monitor.yml بیاورید. قالب TG_TOKEN و TG_CHAT را از قبل دارد.
  4. یک‌بار از Actions ← monitor ← Run workflow اجرایش کنید.

چند نکته:

  • workflow هر ۵ دقیقه اجرا می‌شود. در خود مخزن قالب فقط وقتی دستی اجرا کنید کار می‌کند، پس زمان‌بندی فقط برای کپی شما فعال است.
  • در هر اجرا pulsecheckcli>=0.1,<1 با uvx نصب می‌شود. برای قفل کردن روی یک نسخه‌ی مشخص، مقدار PULSECHECK: را در env: ی workflow عوض کنید.
  • shoutrrr از image داکر اجرا می‌شود. Docker روی runnerهای اوبونتوی گیت‌هاب از قبل نصب است و چیزی لازم نیست نصب کنید.
  • workflow خروجی pulsecheck status --md را در خلاصه‌ی اجرا می‌نویسد، پس هر اجرا بدون داشبورد وضعیت فعلی را نشان می‌دهد.
  • وضعیت با actions/cache ذخیره می‌شود: جدیدترین مورد بازیابی می‌شود و بعد از هر اجرا دوباره ذخیره می‌شود. هیچ commitی زده نمی‌شود.
  • گیت‌هاب ممکن است اجرای زمان‌بندی‌شده را چند دقیقه عقب بیندازد، و اگر ۶۰ روز در مخزن فعالیتی نباشد زمان‌بندی را غیرفعال می‌کند.
  • مخزن اصلی pulsecheck هم یک monitor.yml دارد که از کد منبع checkout شده استفاده می‌کند (uv run)؛ فقط اگر کل پروژه را clone کرده‌اید به کارتان می‌آید.

اگر زمان‌بندی اجرا نمی‌شود: cron بیرونی

schedule خود گیت‌هاب تضمینی نیست. مخزن‌های تازه یا کم‌فعالیت ممکن است ساعت‌ها هیچ اجرای زمان‌بندی‌شده‌ای نگیرند و اجرای */5 اغلب عقب می‌افتد یا حذف می‌شود. workflow قالب repository_dispatch (با نوع رویداد pulsecheck) را هم می‌پذیرد، پس هر زمان‌بند بیرونی (cron-job.org، crontab یک سرور، Cloudflare Cron) می‌تواند آن را راه بیندازد:

curl -X POST \
  -H "Authorization: Bearer $GITHUB_PAT" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/OWNER/REPO/dispatches \
  -d '{"event_type":"pulsecheck"}'

توکن به دسترسی repo (classic) یا Contents: write (fine-grained، فقط همان مخزن) نیاز دارد. هر ۵ دقیقه صدایش بزنید؛ concurrency: monitor از هم‌پوشانی جلوگیری می‌کند. schedule داخلی را هم می‌توانید نگه دارید.

GitLab CI

  1. مخزن را در GitLab بگذارید و pulsecheck.yml خودتان را commit کنید.
  2. در Build ← Pipeline schedules ← New schedule یک زمان‌بندی با cron برابر */5 * * * * بسازید.
  3. image این job داکر ندارد؛ برای همین shoutrrr_bin: auto از فایل اجرایی‌ای استفاده می‌کند که خود job دانلود می‌کند (SHOUTRRR_VERSION در .gitlab-ci.yml).
  4. در Settings ← CI/CD ← Variables همه‌ی ${VAR}‌های فایل را اضافه کنید و رمزها را mask کنید.
  5. job فقط برای pipelineهای زمان‌بندی‌شده اجرا می‌شود و pulsecheck.db را با یک کلید ثابت cache می‌کند. اگر runnerهای شما cache مشترک ندارند، وضعیت بین اجراها از بین می‌رود (بخش عیب‌یابی).

Vercel و Cloudflare Workers

هر دو cron و محدودیت‌های خودشان را دارند؛ مثلاً در Vercel Hobby فقط روزی یک اجرا ممکن است و در Cloudflare رایگان هر اجرای cron ۱۰ میلی‌ثانیه CPU دارد. راه‌اندازی و همه‌ی محدودیت‌ها در سرورلس آمده است.

cron لینوکس

ساده‌ترین راه این است که pulsecheck init خودش cron job را اضافه کند (بخش دستورها). اگر می‌خواهید دستی بنویسید، در crontab -e این خط را بگذارید:

*/5 * * * * PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin" flock -n /tmp/pulsecheck.lock pulsecheck run >> $HOME/pulsecheck.log 2>&1

pulsecheck فایل ~/.config/pulsecheck/pulsecheck.yml و .env کنار آن را خودش پیدا می‌کند، پس هیچ رمزی در crontab نمی‌رود. وضعیت در state_file روی دیسک می‌ماند و flock -n جلوی هم‌پوشانی اجراها را می‌گیرد.

Clone this wiki locally