کتابخانه‌ی استاندارد · زمان و هم‌زمانی

کرون cron

عبارت‌های پنج‌فیلدی کرون و زمان‌بندی دقیقه‌ای که هر کار را روی نخ خودش اجرا می‌کند.

واردسازی کرون

کرون عبارت معمول پنج‌فیلدی کرون را تجزیه می‌کند، آن را با یک زمان تطبیق می‌دهد، دقیقه بعدی را حساب می‌کند و می‌تواند کارهای ثبت‌شده را هر دقیقه اجرا کند. این یک کتابخانه است، نه یک سرویس: داخل برنامه شما اجرا می‌شود، از نخ‌های برنامه شما استفاده می‌کند و با پایان برنامه تمام می‌شود.

پنج فیلد به ترتیب دقیقه، ساعت، روز ماه، ماه و روز هفته هستند. هر فیلد *، یک عدد، یک بازه a-b، یک فهرست a,b,c و یک گام */n یا a-b/n را می‌پذیرد. ماه و روز هفته نام سه‌حرفی انگلیسی مانند jan و mon را هم می‌پذیرند. مثل کرون ویکسی، وقتی هر دو فیلد روز محدود باشند یک زمان با یکی از آن‌ها تطبیق می‌کند؛ وقتی یکی * باشد هر دو باید تطبیق کنند.

*/15 * * * *        هر ربع ساعت
0 9-17 * * mon-fri  هر ساعت از ۹ تا ۱۷ در روزهای کاری
30 2 1 * *          ساعت ۰۲:۳۰ روز اول هر ماه
0 0 29 feb *        روز ۲۹ فوریه

ماکروهای @yearly، @annually، @monthly، @weekly، @daily، @midnight و @hourly به همان پنج فیلد معمول باز می‌شوند.

تجزیه و اجرای بعدی

تجزیه یک عبارت زمان‌بندی برمی‌گرداند که وقتی متن عبارت معتبر نباشد معتبر آن نادرست است. پیش از استفاده معتبر را بررسی کنید. بعدی اولین دقیقه‌ای را برمی‌گرداند که دقیقاً پس از زمان داده‌شده در منطقه زمانی داده‌شده تطبیق می‌کند، یا اگر در محدوده جست‌وجو چیزی پیدا نشود ۰.

cron-quickstart.salam
واردسازی کرون

پایا ZONE := "Invalid/Nowhere"
پایا OFF := ۲۱۰
پایا AFTER := ۱۷۹۲۸۰۰۳۰۰ برگردان صحیح۶۴

تابع show(spec: رشته):
    e := کرون.تجزیه(spec)
    سرچاپ spec، e.معتبر، کرون.بعدی(e، AFTER، ZONE، OFF)
پایان

تابع ریشه:
    show("*/20 * * * *")
    show("@daily")
    show("0 0 29 feb *")
    show("nope")

    e := کرون.تجزیه("*/5 * * * *")
    سرچاپ کرون.تطبیق فیلدها(e، ۱۵، ۱۰، ۱، ۱، ۰)
    سرچاپ کرون.تطبیق فیلدها(e، ۱۶، ۱۰، ۱، ۱، ۰)
    سرچاپ کرون.اختلاف ثانیه منطقه(ZONE، OFF، AFTER)
پایان
خروجی*/20 * * * * true 1792800600 @daily true 1792873800 0 0 29 feb * true 1835382600 nope false 0 true false 12600

زمان‌ها ثانیه UTC از مبدأ هستند. بعدی برای هر دقیقه نامزد، اختلاف منطقه را از پایگاه داده منطقه می‌پرسد، پس تغییر ساعت تابستانی را هم در نظر می‌گیرد. وقتی منطقه وجود نداشته باشد، هر فراخوانی fallback_minutes را به کار می‌برد؛ همان کاری که آزمون‌ها برای مستقل ماندن از ماشین می‌کنند.

تطبیق زمانی که از قبل دارید

تطبیق فیلدها دقیقه، ساعت، روز، ماه و روز هفته محلی را مستقیم می‌گیرد، پس می‌توانید آن را روی مقدارهای ساعت خودتان یا پایگاه داده به کار ببرید. تطبیق محلی یک لحظه دیواری به ثانیه را می‌گیرد که از قبل با اختلاف منطقه جابه‌جا شده و همان چیزی است که زمان‌بند درون خود استفاده می‌کند.

cron-match.salam
واردسازی کرون

تابع ریشه:
    e := کرون.تجزیه("0 9-17 * * mon-fri")
    سرچاپ کرون.تطبیق فیلدها(e، ۰، ۹، ۱، ۱، ۱)
    سرچاپ کرون.تطبیق فیلدها(e، ۳۰، ۹، ۱، ۱، ۱)
    سرچاپ کرون.تطبیق محلی(e، ۱۷۹۳۰۰۵۲۰۰ برگردان صحیح۶۴)
پایان
خروجیtrue false true

روزهای هفته ۰ برای یکشنبه تا ۶ برای شنبه هستند؛ ۷ هم پذیرفته و مثل یکشنبه رفتار می‌شود. تطبیق فیلدها برای عبارتی که معتبر آن نادرست است نادرست برمی‌گرداند.

منطقه‌ها و اختلاف‌ها

زمان‌بند برای همه کارها یک منطقه نگه می‌دارد. تنظیم منطقه نام و اختلاف پشتیبان به دقیقه را می‌گذارد که وقتی نام بارگذاری نشود به کار می‌رود. اختلاف ثانیه منطقه اختلاف هر منطقه در یک لحظه را برمی‌گرداند که بیرون از زمان‌بند هم مفید است.

cron.SetZone("Asia/Tehran", 210)
off := cron.OffsetSeconds("Asia/Tehran", 210, 1700000000 as i64)
println off / (60 as i64)

منطقه پیش‌فرض UTC با پشتیبان ۰ است. تنظیم منطقه را پیش از اجرا یا اجرا در پس‌زمینه صدا بزنید؛ تغییر بعدی روی دقیقه بعد اثر دارد، نه روی کاری که در حال اجراست.

کارها و زمان‌بند

افزودن یک تابع را با یک نام و یک عبارت ثبت می‌کند و شناسه کار را برمی‌گرداند، یا وقتی عبارت تجزیه نشود ‎-۱. گرداننده کار شناسه کار را به شکل i64 می‌گیرد. همه کارها را پیش از شروع زمان‌بند ثبت کنید.

cron-schedule.salam
واردسازی حافظه
واردسازی زمان
واردسازی کرون

ناپایا hits := پوچ برگردان صحیح۶۴*

تابع tick(id: صحیح۶۴):
    اتمی‌بیفزا(hits، ۱ برگردان صحیح۶۴)
    سرچاپ "job"، id، کرون.نام(id برگردان صحیح)
پایان

تابع ریشه:
    hits = حافظه.تخصیص صفرشده(۸ برگردان طبیعی۶۴) برگردان صحیح۶۴*
    کرون.تنظیم منطقه("Invalid/Nowhere"، ۲۱۰)

    every := کرون.افزودن("every minute"، "* * * * *"، tick)
    nightly := کرون.افزودن("nightly"، "0 3 * * *"، tick)
    broken := کرون.افزودن("broken"، "nope"، tick)
    سرچاپ کرون.تعداد()، کرون.نام(every)، کرون.نام(nightly)، broken
    سرچاپ کرون.مشغول است(every)

    started := کرون.اجرای موعد(۱۷۹۲۸۰۰۳۰۰ برگردان صحیح۶۴)
    ناپایا waited := ۰
    تا اتمی‌بخوان(hits) == (۰ برگردان صحیح۶۴) یا waited >= ۲۰۰:
        زمان.خواب(۱۰)
        waited += ۱
    پایان
    سرچاپ "started"، started، "hits"، اتمی‌بخوان(hits)
    سرچاپ کرون.مشغول است(every)

    کرون.اجرا در پس‌زمینه()
    کرون.توقف()
پایان

اجرا مسدود می‌شود و کارهای موعد هر دقیقه را یک بار اجرا می‌کند؛ اجرا در پس‌زمینه همین حلقه را روی نخ خودش اجرا می‌کند و فوراً برمی‌گردد. اجرای موعد کارهای موعد در زمان داده‌شده را بدون انتظار برای دقیقه بعد اجرا می‌کند، همان کاری که آزمون یا یک تیک دستی می‌کند. در هر شکل، کاری که از اجرای قبلی هنوز مشغول است رد می‌شود و در صف نمی‌ماند، پس کار کند روی هم انبار نمی‌شود.

تعداد، نام و مشغول است جدول را بررسی می‌کنند. توقف از حلقه می‌خواهد پس از کار جاری تمام شود؛ منتظر کار در حال اجرا نمی‌ماند و می‌شود آن را از گرداننده سیگنال یا نخ دیگری صدا زد.

cron.SetZone("UTC", 0)
cron.Add("cleanup", "0 3 * * *", cleanup)
cron.RunBackground()
time.Sleep(60000)
cron.Stop()

آنچه باید بدانید

  • دقت یک دقیقه است. ثانیه و زمان‌بندی ریزتر از دقیقه ندارد.
  • کارها روی نخ خودشان و در همان فرایند اجرا می‌شوند. یک خطا، خواندن مسدود یا حلقه طولانی در یک کار روی کل برنامه اثر می‌گذارد.
  • توقف همکارانه است: حلقه پرچم را بین دقیقه‌ها و هنگام خواب بررسی می‌کند، پس کاری که لغو خودش را نادیده بگیرد می‌تواند ادامه پیدا کند.
  • بسته کارها را ذخیره نمی‌کند. اگر پس از راه‌اندازی دوباره لازمشان دارید، نام و عبارت را خودتان نگه دارید و هنگام شروع دوباره ثبت کنید.
  • وقتی هر دو فیلد روز ماه و روز هفته محدود باشند، با هر کدام تطبیق کند کافی است، مثل کرون ویکسی. این اغلب غافلگیرکننده است؛ تا می‌توانید فقط یک فیلد روز بدهید.

گونه‌ها

عبارت زمان‌بندی Expr

ساختار عبارت زمان‌بندی
یک زمان‌بندی تجزیه‌شده: پنج ماسک بیتی، دو پرچم که می‌گویند کدام فیلد روز ستاره بوده و یک پرچم معتبر.
نامانگلیسیگونهتوضیح
دقیقه‌هاminutesصحیح۶۴ = 0دقیقه‌های ساعت که تطبیق می‌کنند، به شکل ماسک بیتی.
ساعت‌هاhoursصحیح۶۴ = 0ساعت‌های روز که تطبیق می‌کنند، به شکل ماسک بیتی.
روزهاdaysصحیح۶۴ = 0روزهای ماه که تطبیق می‌کنند، به شکل ماسک بیتی.
ماه‌هاmonthsصحیح۶۴ = 0ماه‌هایی که تطبیق می‌کنند، به شکل ماسک بیتی.
روزهای هفتهweekdaysصحیح۶۴ = 0روزهای هفته که تطبیق می‌کنند، به شکل ماسک بیتی؛ یکشنبه بیت ۰ است.
همه روزهاdom_starمنطقی = درستوقتی فیلد روز ماه * بوده درست است.
همه روزهای هفتهdow_starمنطقی = درستوقتی فیلد روز هفته * بوده درست است.
معتبرokمنطقی = نادرستوقتی متن تجزیه شده درست است؛ هر تابع دیگر عبارتی را که معتبر نباشد رد می‌کند.

تابع‌ها

تجزیه Parse

تابع تجزیه(spec: رشته): عبارت زمان‌بندی
پنج فیلد یا یک ماکرو مانند @daily را تجزیه می‌کند. در تعداد فیلد نادرست، عدد خارج از بازه، بازه شکسته، گام صفر یا نام ناشناس، عبارتی با معتبر نادرست برمی‌گرداند.
cron-Parse.salam
واردسازی کرون

پایا ZONE := "Invalid/Nowhere"
پایا OFF := ۲۱۰
پایا AFTER := ۱۷۹۲۸۰۰۳۰۰ برگردان صحیح۶۴

تابع show(spec: رشته):
    e := کرون.تجزیه(spec)
    سرچاپ spec، e.معتبر، کرون.بعدی(e، AFTER، ZONE، OFF)
پایان

تابع ریشه:
    show("*/20 * * * *")
    show("@daily")
    show("0 0 29 feb *")
    show("nope")

    e := کرون.تجزیه("*/5 * * * *")
    سرچاپ کرون.تطبیق فیلدها(e، ۱۵، ۱۰، ۱، ۱، ۰)
    سرچاپ کرون.تطبیق فیلدها(e، ۱۶، ۱۰، ۱، ۱، ۰)
    سرچاپ کرون.اختلاف ثانیه منطقه(ZONE، OFF، AFTER)
پایان

تطبیق فیلدها MatchFields

تابع تطبیق فیلدها(e: عبارت زمان‌بندی، minute: صحیح، hour: صحیح، day: صحیح، month: صحیح، weekday: صحیح): منطقی
وقتی دقیقه، ساعت، روز، ماه و روز هفته محلی با عبارت تطبیق کنند درست است. روزهای هفته ۰ برای یکشنبه تا ۶ برای شنبه هستند.
cron-Match.salam
واردسازی کرون

تابع ریشه:
    e := کرون.تجزیه("0 9-17 * * mon-fri")
    سرچاپ کرون.تطبیق فیلدها(e، ۰، ۹، ۱، ۱، ۱)
    سرچاپ کرون.تطبیق فیلدها(e، ۳۰، ۹، ۱، ۱، ۱)
    سرچاپ کرون.تطبیق محلی(e، ۱۷۹۳۰۰۵۲۰۰ برگردان صحیح۶۴)
پایان
خروجیtrue false true

تطبیق محلی MatchesLocal

تابع تطبیق محلی(e: عبارت زمان‌بندی، local: صحیح۶۴): منطقی
وقتی یک لحظه دیواری به ثانیه که از قبل با اختلاف منطقه جابه‌جا شده با عبارت تطبیق کند درست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Match.salam

اختلاف ثانیه منطقه OffsetSeconds

تابع اختلاف ثانیه منطقه(zone: رشته، fallback_minutes: صحیح، epoch: صحیح۶۴): صحیح۶۴
اختلاف یک منطقه زمانی در یک لحظه، به ثانیه؛ وقتی منطقه بارگذاری نشود پشتیبان به دقیقه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Parse.salam

بعدی Next

تابع بعدی(e: عبارت زمان‌بندی، after: صحیح۶۴، zone: رشته، fallback_minutes: صحیح): صحیح۶۴
اولین دقیقه‌ای که دقیقاً پس از after تطبیق می‌کند، به ثانیه UTC، یا ۰ وقتی در محدوده جست‌وجو چیزی پیدا نشود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Parse.salam

تنظیم منطقه SetZone

تابع تنظیم منطقه(name: رشته، fallback_minutes: صحیح)
نام منطقه و اختلاف پشتیبان را برای زمان‌بند می‌گذارد. پیش‌فرض UTC با ۰ است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Parse.salam

افزودن Add

تابع افزودن(name: رشته، spec: رشته، fn: صحیح۶۴): صحیح
یک گرداننده را با نام و زمان‌بندی ثبت می‌کند و شناسه کار را برمی‌گرداند، یا وقتی زمان‌بندی تجزیه نشود ‎-۱. گرداننده شناسه کار را به شکل i64 می‌گیرد.
cron-Schedule.salam
واردسازی حافظه
واردسازی زمان
واردسازی کرون

ناپایا hits := پوچ برگردان صحیح۶۴*

تابع tick(id: صحیح۶۴):
    اتمی‌بیفزا(hits، ۱ برگردان صحیح۶۴)
    سرچاپ "job"، id، کرون.نام(id برگردان صحیح)
پایان

تابع ریشه:
    hits = حافظه.تخصیص صفرشده(۸ برگردان طبیعی۶۴) برگردان صحیح۶۴*
    کرون.تنظیم منطقه("Invalid/Nowhere"، ۲۱۰)

    every := کرون.افزودن("every minute"، "* * * * *"، tick)
    nightly := کرون.افزودن("nightly"، "0 3 * * *"، tick)
    broken := کرون.افزودن("broken"، "nope"، tick)
    سرچاپ کرون.تعداد()، کرون.نام(every)، کرون.نام(nightly)، broken
    سرچاپ کرون.مشغول است(every)

    started := کرون.اجرای موعد(۱۷۹۲۸۰۰۳۰۰ برگردان صحیح۶۴)
    ناپایا waited := ۰
    تا اتمی‌بخوان(hits) == (۰ برگردان صحیح۶۴) یا waited >= ۲۰۰:
        زمان.خواب(۱۰)
        waited += ۱
    پایان
    سرچاپ "started"، started، "hits"، اتمی‌بخوان(hits)
    سرچاپ کرون.مشغول است(every)

    کرون.اجرا در پس‌زمینه()
    کرون.توقف()
پایان

تعداد Count

تابع تعداد(): صحیح
تعداد کارهای ثبت‌شده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam

نام Name

تابع نام(id: صحیح): رشته
نام یک کار.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam

مشغول است IsBusy

تابع مشغول است(id: صحیح): منطقی
تا وقتی کار از یک موعد در حال اجراست درست است؛ زمان‌بند کار مشغول را رد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam

اجرای موعد RunDue

تابع اجرای موعد(now: صحیح۶۴): صحیح
هر کار موعد در زمان UTC داده‌شده را روی نخ خودش شروع می‌کند و تعداد شروع‌شده‌ها را برمی‌گرداند. کار مشغول رد می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam

اجرا Run

تابع اجرا()
مسدود می‌شود و کارهای موعد را هر دقیقه یک بار تا توقف اجرا می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam

اجرا در پس‌زمینه RunBackground

تابع اجرا در پس‌زمینه()
همین حلقه را روی نخ خودش شروع می‌کند و فوراً برمی‌گردد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam

توقف Stop

تابع توقف()
از حلقه زمان‌بند می‌خواهد پس از کار جاری تمام شود. کار در حال اجرا قطع نمی‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: cron-Schedule.salam