انتقل إلى المحتوى
النوعإمكان جديد
المرحلةالإنتاج
مستوى الصعوبةبسيط
المهمةأتمتة مهمّة
لـالمؤسسون الفرادى
لـمطورو الواجهة الخلفية
الخدماتCron
الخدماتFiles
لماذا Hoodyأصيل لـ HTTP
النوعإمكان جديد
المرحلةالإنتاج
مستوى الصعوبةبسيط
المهمةأتمتة مهمّة
لـالمؤسسون الفرادى
لـمطورو الواجهة الخلفية
الخدماتCron
الخدماتFiles
لماذا Hoodyأصيل لـ HTTP
النوعإمكان جديد
المرحلةالإنتاج
مستوى الصعوبةبسيط
المهمةأتمتة مهمّة
لـالمؤسسون الفرادى
لـمطورو الواجهة الخلفية
الخدماتCron
الخدماتFiles
لماذا Hoodyأصيل لـ HTTP
النوعإمكان جديد
المرحلةالإنتاج
مستوى الصعوبةبسيط
المهمةأتمتة مهمّة
لـالمؤسسون الفرادى
لـمطورو الواجهة الخلفية
الخدماتCron
الخدماتFiles
لماذا Hoodyأصيل لـ HTTP
CRON · FILES · SELF-RETIRING

مهام تنظيف تجدول تقاعدها بنفسها

وفّر مُدخل cron مُداراً يوم بدء التنظيف. اضبط expires_at على بضعة أيام بعد آخر تشغيل متوقّع. السكربت يقطع العمل ليلاً، ثم يُرسل DELETE لنفسه حين لا يبقى شيء. لا تذكير في التقويم، لا crontab زومبي، ولا مراجعة سنوية لتنظيف-المُنظِّفات.

توثيق cron
cleanup-stale-uploads.sh
# tail of cleanup-stale-uploads.sh
removed=$(find /uploads -mtime +90 -delete -print | wc -l)
echo "$removed files removed"

# self-aware tail: nothing left → retire
if [ -z "$(ls /uploads)" ]; then
  curl -fsS -X DELETE \
    "$CRON_URL/entries/$ENTRY_ID"
fi

الذيل الواعي لذاته. مُدخل cron هو السطر الأخير من سكربته الخاص.

تنظيف بعمر مُنتهٍ، بالبناء

ثلاث مراحل منفصلة. كل انتقال آلي، ولا واحد منها يحتاج إنساناً ليتذكّر. المُدخل يعرف متى ينتهي عمله ومتى تنقضي خانته في التقويم.

دورة الحياة · جدولة → تقطيع → حذف ذاتيمُدخل واحد، حياة مُنتهية
1 · SCHEDULE

أرسل POST لمُدخل واحد يوم بدء التنظيف

الجدول @daily، الأمر يُشير إلى سكربت تقطيع، expires_at مضبوط على ما بعد آخر تشغيل متوقّع بقليل. الموعد النهائي في المُدخل — لا في وثيقة Notion، ولا في خيط Slack.

2 · SLICE

السكربت يقتطع كل ليلة، بلطف

كل تشغيل يحذف شريحة من البيانات القديمة كي لا تُرهَق قاعدة البيانات. اليوم الأول قد يمسح 247 ملفاً؛ اليوم السادس فقط 1. الإيقاع محدود بما تبقّى فعلاً.

3 · SELF-DELETE

حين ينتهي العمل، يتقاعد المُدخل

آخر كتلة في السكربت تتفقّد ما إذا كان الهدف فارغاً. إن نعم، تُطلق DELETE /entries/[self]. وإن لم تفعل لسبب ما، تُطلق expires_at شبكة الأمان بعد بضعة أيام.

محرّكان مستقلّان — تحقّق السكربت الذاتي وexpires_at على مستوى API — يتلاقيان في النتيجة نفسها: سطر في crontab لا يعيش أطول من غرضه.

استدعاءا HTTP، تنظيف واحد مُنتهٍ

Hoody Cron غلاف JSON-CRUD حول crontab النظام. POST يُنشئ المُدخل؛ DELETE يُزيله؛ expires_at هو شبكة الأمان. السكربت الذي يعمل ليلاً هو من يعرف متى انتهى — لذا هو من يستدعي DELETE.

create-entry.sh
اليوم 0 · POST
# day 0 — provision the cleanup
curl -X POST \
  https://cron.containers.hoody.com/users/me/entries \
  -H "Content-Type: application/json" \
  -d '["schedule":"@daily","command":"/srv/jobs/cleanup-stale-uploads.sh","expires_at":"2026-05-05T00:00:00Z"]'

# response
HTTP/1.1 201 Created
{ "id":"f3a1", "expires_at":"2026-05-05T00:00:00Z", "enabled":true }
cleanup-stale-uploads.sh
اليوم 7 · DELETE
# inside the cron command itself
if [ -z "$(ls /uploads)" ]; then
  curl -X DELETE \
    "$CRON_URL/entries/$ENTRY_ID"
fi

# response
HTTP/1.1 204 No Content
# entry f3a1 was here. f3a1 deleted itself.

$ENTRY_ID هو UUID المُرجع من POST. مرره عبر سطر الأوامر / argv حتى يقرأه السكريبت من ملف أو argv. بأي الطريقتين، إدخال cron يحذف إدخال cron.

ما الذي يفتحه التنظيف ذاتي التقاعد

ليس الحذف هو ما يهمّ. بل أنه لا أحد يحتاج أن يتذكّر وجود أيّ من هذا بعد ثلاثة أشهر من الآن.

PRESSURE-FREE PACING

شريحة بعد شريحة، لا دفعة واحدة

@daily يعمل كل 24 ساعة. السكربت يحذف شريحة من البيانات القديمة — بضعة آلاف من الملفات، بضعة آلاف من الصفوف — ويخرج. قاعدة البيانات تبقى هادئة؛ منحنى الحمل يبدو وكأن شيئاً لم يحدث.

بلا CRONTAB ZOMBIE

السطر لا يعيش أطول من المهندس

expires_at في المُدخل بصيغة JSON. حين يُطلق، يُحذف السطر من crontab النظام. ثلاثة مهندسين من الآن، لا أحد يتصفّح 200 سطر متسائلاً ماذا يفعل cleanup-stale-uploads-v3 بعد.

زناد اثنين، نتيجة واحدة

Self-DELETE مع شبكة أمان expires_at

السكربت يُرسل DELETE لنفسه ليلة انتهاء العمل. إن تخطّى خلل ذلك المسار، expires_at يُقاعد المُدخل بعد بضعة أيام. آليتان مستقلّتان؛ واحدة منهما ستُطلق.

كيف يتسع هذا

كل مُدخل مُدار هو صفّ JSON يحقنه API في crontab النظام. التوسّع محدود بما يستطيع cron نفسه أن يحمله، لا بـ Hoody.

  1. إيقاع التشغيل1 / يوم

    @daily هو الإيقاع المعتاد للتنظيف. إن احتجت تمريرات أكثر تواتراً تستطيع استخدام تعابير الخمسة حقول وصولاً إلى * * * * * — دقّة الدقيقة.

  2. عمر المُدخلexpires_at

    طابع زمني ISO-8601 على المُدخل. حين يمضي، يُزيل API السطر في الكنس التالي. التنظيف لا يتمدّد قطّ بعد موعده النهائي.

  3. تفكيك HTTPDELETE · 204

    DELETE /users/[user]/entries/[id] من داخل الأمر قيد التشغيل يعمل لأن عفريت cron لا يقفل crontab الخاص به — API يكنس التغيير بأمان.

تعابير cron قياسية من خمسة حقول مع الماكروات (@hourly, @daily, @weekly, @monthly, @yearly). عزل لكل مستخدم؛ كل مستخدم نظام يحصل على crontab خاص به. صفحة Cron في Hoody Kit توثّق كلّاً من المُدخلات المُدارة وaccess crontab الخام إن احتجت الشكل الأقدم.

التنظيف يعمل ليلاً حتى يختفي الشيء الذي يجري تنظيفه.

قبل · تذكيرات تقويم، أسطر cron ميّتةبعد · إدخال CRON يعرف متى انتهى
قبل// TODO: حذف هذا حين /uploads فارغ (2026؟)تعليق سيقرؤه نفسك المستقبلي مرة واحدة ثم لا يقرؤه أبداً.
الآنDELETE /entries/$ENTRY_ID · expires_at: 2026-05-05تفكيك يُطلَق من السكربت وموعد نهائي مُدرَج في المُدخل ذاته.
مرجع Cron API

ما الذي يحلّ هذا محلّه

في أيّ مكان يُفترض فيه بمهمة تنظيف أن تختفي من تلقاء نفسها — هذه هي الأنماط التي يحلّ هذا محلّها:

  • مهام cron تنظيف زومبيأسطر من 2022 لا أحد يجرؤ على حذفها
  • // TODO: حذف هذا حين X فارغتعليق أصبح دائماً
  • سكربتات حارس يدويةزميل يُشغّلها فصلياً، حين يتذكّر
  • Kubernetes CronJobs لا تحذف نفسها أبداًttlSecondsAfterFinished على البود، لا على الجدول
  • مُدراء دورة حياة مخصّصون واعون لذاتهمخدمة محلّية تراقب خدماتك الأخرى
  • سياسات دورة حياة مُدارة بـ TerraformPlan، apply، بعد ستة أشهر لا تزال في tfstate

وفّر التنظيف. اضبط تاريخ تقاعده. وامشِ بعيداً.

اقرأ توثيق Cron

اقرأ حالات أخرى