Přeskočit obsah
V
Pro vývojáře
Architektura, konvence, jádro systému a bezpečnost
Začínáme / Naplánované úlohy

Naplánované úlohy#

Všechno, co se v systému děje samo od sebe. Seznam se generuje z kódu, takže vyjmenovává přesně ty úlohy, které v repozitáři opravdu jsou.

Jak se úloha volá#

GET /cron/<modul>/<presenter>/<akce>?token=<cron.token>
Věc Jak to funguje
Ověření dotaz musí nést ?token= shodný s nastavením cron.token (skupina 1)
Odpověď vždy JSON — {"status":"ok",…}, {"status":"error",…} nebo {"status":"skipped"}
Souběh druhá instance téže úlohy skončí skipped, nečeká se

Bez tokenu vrací 403 — a prázdný token nepustí NIKOHO

Kontrola porovnává očekávanou a poslanou hodnotu; když cron.token v nastavení chybí, neprojde ani prázdný dotaz. Po nasazení na nový server je to první věc k vyplnění, jinak neběží vůbec nic a nikde to nekřičí.

Zámek souběhu je fail-open

Dokud tabulka zámků neexistuje, skipped se nikdy nevrátí a úlohy se můžou překrývat. Je to schválně — chybějící tabulka nemá zastavit provoz — ale znamená to, že „nikdy jsem skipped neviděl“ není důkaz, že zámek funguje.

Jak poznat, že úloha běžela

Podle odpovědi, ne podle toho, že „nic nespadlo“. {"status":"ok"} vrací i úloha, která neudělala nic — počty jsou v dalších klíčích odpovědi.

Plánovač — jedna adresa místo padesáti#

Úloh je kolem sedmdesáti. Zadávat je na hostingu po jedné se při každé nové úloze zapomene, proto je volá plánovač: hosting volá jedinou adresu

GET /cron/system/scheduler/run?token=<cron.token>        (každých 5 minut)

a plánovač podle tabulky cms_system_cron_jobs rozhodne, které úlohy jsou právě na řadě, a volá je jednu po druhé HTTP na vlastní adresu se stejným tokenem — žádná úloha se nepřepisuje. Správce ho spravuje v administraci (Nastavení → Cron, viz Plánovač úloh).

Věc Jak to funguje
Katalog atribut #[CronJob(frequency: …, outbound: …, query: […])] na veřejné action*() cron presenteru — zdroj pravdy; docblock (URL:, Frekvence:) zůstává kvůli tomuto přehledu
Nová úloha bez atributu ji plánovač nezná — test CronJobCatalogTest shodí každou action* bez něj. Do tabulky se doplní sama při dalším volání plánovače (bez migrace)
Frekvence text every:N · daily:HH:MM · weekly:D@HH:MM · monthly:D@HH:MM · manual (CronFrequency); „jednorázově po nasazení“ a opravné úlohy = manual
outbound povinný argument (bez výchozí hodnoty): true = posílá e-maily/SMS, vystavuje doklady, maže/anonymizuje data uživatelů, volá platební brány nebo notifikuje hlídací psy. Odchozí úloha je po objevení vypnutá. Při nejistotě true
query pevné parametry volání (např. sitemapy ['save' => '1'] — bez save vrací jen náhled)
Moduly cms_system_cron_jobs.module_id z cesty /cron/<modul>/… (cms_system_modules); úlohy modulu s activated = 0 se nezobrazují ani nespouštějí, modul system je vždy
Běh rozpočet 45 s, nejdéle neběžící první; chyba nebo timeout = stav error a další pokus až v dalším termínu; „skipped“ (zámek úlohy) se zkusí při dalším volání. Odpověď se ukládá zkrácená (≤ 500 znaků) a token se do ní ani do logu nikdy nedostane
Souběh dva plánovače: druhý skončí skipped na zámku (cron.system.scheduler.run) jako každý cron
Plánovač není úloha SchedulerPresenter katalog vynechává (CronJobCatalog::EXCLUDED_PRESENTERS)

Plánovač volá úlohy po HTTP na vlastní adresu

Na jednovláknovém php -S (lokální dev server) se takové volání zasekne a skončí timeoutem — server nemůže obsloužit druhý požadavek, dokud nedoběhl první. Ověřuj s více procesy: PHP_CLI_SERVER_WORKERS=4 php -S ….

Přidáváš novou cron akci?

  1. Přidej #[CronJob(frequency: '…', outbound: true|false)] nad action*() (a query, pokud jsou potřeba).
  2. Doplň název úlohy do překladů admin.system.presenters.cronJob.jobs.<modul>.<presenter>.<akce> (cs/en/sk); bez překladu se v administraci ukáže jen adresa.
  3. Ostatní (tabulka, výpis, plánování) se dělá samo.

Nasazení#

Sloupec Doporučený interval je návrh ze zdrojového kódu — z něj se skládá crontab. Například:

*/1  * * * *  curl -s "https://web.cz/cron/system/email-queue/send?token=TOKEN"
*/5  * * * *  curl -s "https://web.cz/cron/store/reservation/expire?token=TOKEN"
15   3 * * *  curl -s "https://web.cz/cron/blog/sitemap/article?token=TOKEN"

Nezapojená úloha NIKDY neběží — a nic se nerozbije

Nespuštěná úloha nevyhodí chybu. Jen se přestane dít to, co měla dělat: nevyprší košíky, nevygenerují se faktury, neuklidí se data. Odhalí se to obvykle až tím, že něco „nějak narostlo“. Proto po instalaci projděte celý seznam níž, ne jen to, co zrovna používáte.

Ne všechno je periodické

Několik úloh je opravných nebo jednorázových — mají v intervalu napsané „ručně“. Do crontabu nepatří; pustí se, když je potřeba.

Sitemap index až po ostatních sitemapách

Skládá rozcestník z už vygenerovaných souborů. Když poběží první, sestaví ho z toho, co zbylo po minulém běhu.

Přehled úloh#

Sdílené#

Endpoint Co dělá Doporučený interval
/cron/base/newsletter/dispatch Dispatches executing newsletters into the e-mail queue in batches ; the queue cron sends them every 5 minutes
/cron/base/rating/recalc Self-heal přepočet agregátu rating threadů periodicky, např. jednou denně (drift je výjimečný, ne hot-path)

Inzerce#

Endpoint Co dělá Doporučený interval
/cron/bazaar/advert/notice-expiration Pošle BZ_ADVERT_EXPIRATION_NOTICE inzerátům, kterým do N dní vyprší expirace (N = setting 5/advert.expiration.noticeDays) denně (např. v noci)
/cron/bazaar/advert/delete-expired Tiše označí deleted=1 inzeráty, jimž od expirace uplynulo víc než M dní (M = setting 5/advert.expiration.deleteDays) denně
/cron/bazaar/advert/recount-prices Přepočítá denormalizovaný sloupec price u všech inzerátů z parametru price periodicky, např. každých 10–15 minut
/cron/bazaar/category/recount Přepočítá denormalizovaný advert_count u všech kategorií periodicky, např. každých 10–15 minut
/cron/bazaar/elastic/reindex Full reindex inzerátů do nové verze indexů + atomický alias swap (bezvýpadkově, Redis lock proti souběhu) 1× denně v noci
/cron/bazaar/elastic/sync Inkrementální sync: doindexuje inzeráty vložené od watermarku (Redis es::watermark:bazaar_advert, 5 min překryv) + orphan cleanup (dokumenty bez DB řádku) každých 10 minut
/cron/bazaar/sitemap/category Sitemapa všech aktivních kategorií Bazaaru s hreflang variantami denně v noci
/cron/bazaar/sitemap/advert Sitemapa aktivních inzerátů, automaticky rozdělená na soubory podle rozsahů ID (velikost podle počtu jazyků) denně v noci
/cron/bazaar/watchdog-email/send Mód 1 — okamžité posílání průběžně, např. každých 5–10 minut
/cron/bazaar/watchdog-email/digest Mód 2 — denní digest jednou denně, např. ve 23:00
/cron/bazaar/watchdog-email/purge-old Retence fronty hlídacího psa (PERF-8): smaže ODESLANÉ a ZRUŠENÉ řádky _watchdog_email_rel starší než N dní a e-maily (_watchdog_emails + texty), na které už žádný řádek neukazuje denně

Blog#

Endpoint Co dělá Doporučený interval
/cron/blog/elastic/reindex Full reindex článků do nové verze indexů + atomický alias swap (bezvýpadkově, Redis lock proti souběhu) 1× denně v noci
/cron/blog/elastic/sync Inkrementální sync: doindexuje články změněné od watermarku (Redis es::watermark:blog_article, 5 min překryv) + orphan cleanup (dokumenty bez DB řádku) každých 10 minut
/cron/blog/sitemap/article — denně v noci
/cron/blog/sitemap/event — denně v noci
/cron/blog/sitemap/news — denně v noci
/cron/blog/sitemap/article-category — denně v noci
/cron/blog/sitemap/event-category — denně v noci
/cron/blog/sitemap/news-category — denně v noci

Katalog firem#

Endpoint Co dělá Doporučený interval
/cron/comcat/advert/notice-expiration Pošle CC_ADVERT_EXPIRATION_NOTICE inzerátům, kterým do N dní vyprší expirace (N = setting 5/advert.expiration.noticeDays) denně (např. v noci)
/cron/comcat/advert/delete-expired Tiše označí deleted=1 inzeráty, jimž od expirace uplynulo víc než M dní (M = setting 5/advert.expiration.deleteDays) denně
/cron/comcat/category/recount Přepočítá denormalizovaný advert_count u všech kategorií periodicky, např. každých 10–15 minut
/cron/comcat/elastic/reindex Full reindex firemních profilů (Comcat Advert) do nové verze indexů + atomický alias swap (bezvýpadkově, Redis lock proti souběhu) 1× denně v noci
/cron/comcat/elastic/sync Inkrementální sync: doindexuje inzeráty vložené od watermarku (Redis es::watermark:comcat_advert, 5 min překryv) + orphan cleanup (dokumenty bez DB řádku) každých 10 minut
/cron/comcat/sitemap/category Sitemapa všech aktivních kategorií Comcatu s hreflang variantami denně v noci
/cron/comcat/sitemap/advert Sitemapa aktivních inzerátů, automaticky rozdělená na soubory podle rozsahů ID (velikost podle počtu jazyků) denně v noci
/cron/comcat/watchdog-email/send Mód 1 — okamžité posílání průběžně, např. každých 5–10 minut
/cron/comcat/watchdog-email/digest Mód 2 — denní digest jednou denně, např. ve 23:00
/cron/comcat/watchdog-email/purge-old Retence fronty hlídacího psa (PERF-8): smaže ODESLANÉ a ZRUŠENÉ řádky _watchdog_email_rel starší než N dní a e-maily (_watchdog_emails + texty), na které už žádný řádek neukazuje denně

Company#

Endpoint Co dělá Doporučený interval
/cron/company/sitemap/service Sitemap of the company service detail pages (Front:Company:Service:detail) daily, at night (before the sitemap index at 04:30)

Diskuze#

Endpoint Co dělá Doporučený interval
/cron/discussion/elastic/reindex Full reindex kořenů vláken (level=1) do nové verze indexu + atomický alias swap 1× denně v noci
/cron/discussion/elastic/sync Inkrementální sync: doindexuje nová vlákna od watermarku (Redis es::watermark:discussion_message, 5 min překryv) + orphan cleanup každých 10 minut
/cron/discussion/sitemap/message Sitemapa top-level (level=1) aktivních zpráv, automaticky rozdělená podle rozsahů ID (velikost podle počtu jazyků) denně v noci
/cron/discussion/sitemap/category Sitemapa všech kategorií Diskuze denně v noci

E-shop#

Endpoint Co dělá Doporučený interval
/cron/eshop/cart/cleanup Maže opuštěné košíky, kterým vypršela retenční lhůta denně v noci
/cron/eshop/complaint/expire Uzavírá reklamace, kterým vypršela lhůta na vyřízení denně (lhůty se počítají ve dnech)
/cron/eshop/elastic/reindex Full reindex prodejních karet do nové verze indexů + atomický alias swap (bezvýpadkově, Redis lock proti souběhu) 1× denně v noci
/cron/eshop/elastic/sync Inkrementální sync: doindexuje karty změněné od watermarku (Redis es::watermark:eshop_product_set, 5 min překryv) + orphan cleanup (dokumenty bez DB řádku) každých 10 minut
/cron/eshop/feed/generate Generuje XML feedy pro srovnávače zboží à hodinu (nebo dle požadavku srovnávače)
/cron/eshop/order/expire Ruší nezaplacené objednávky a dogeneruje chybějící doklady à hodinu
/cron/eshop/order/cancel-unpaid Cancels unpaid orders and generates missing invoices daily (the period is counted in days)
/cron/eshop/order/invoice Ruší nezaplacené objednávky a dogeneruje chybějící doklady à 15 minut
/cron/eshop/price/recalc Aktivuje naplánované ceny a srovná denormalizovaný sloupec ceny à 15 minut (aktivuje naplánované ceny — delší interval je oddálí)
/cron/eshop/product-import/run Spustí nejstarší job ve frontě každou minutu
/cron/eshop/sitemap/category Sitemapa všech kategorií e-shopu s hreflang variantami denně v noci
/cron/eshop/sitemap/product Sitemapa viditelných produktů (prodejních karet), automaticky rozdělená na soubory podle rozsahů ID (velikost podle počtu jazyků) denně v noci

Fakturace#

Endpoint Co dělá Doporučený interval
/cron/invoicer/payment/generate Vystavuje doklady k zaplaceným platbám podle pravidel modulu často (např. každých 15 min) — doklady vzniknou krátce po změně stavu platby, ale MIMO
/cron/invoicer/schedule/generate Vystavuje opakované faktury podle rozvrhů, kterým nastalo datum denně

Sklad#

Endpoint Co dělá Doporučený interval
/cron/store/batch/expiry-alert Upozorňuje na šarže, kterým se blíží expirace denně ráno
/cron/store/reservation/expire Uvolňuje skladové rezervace, kterým vypršela platnost à 5 minut
/cron/store/stock/recount Noční přepočet skladu — srovná rezervovaná množství, šarže a ceny karet denně v noci
/cron/store/stock/low-stock-alert Upozornění na karty pod minimální zásobou — jeden souhrnný e-mail na stock.lowStock.email, karta se ohlásí jen jednou, dokud se nevrátí na minimum denně ráno

Systém#

Endpoint Co dělá Doporučený interval
/cron/system/asset-thumbnail-catchup/generate Doplní image varianty (poster z prvního framu) pro video Assety, kterým varianty zatím nebyly fyzicky vygenerovány — typicky když v době uploadu ffmpeg chyběl nebo selhal denně v noci
/cron/system/asset-thumbnail-catchup/backfill-meta Doplní Asset.meta (reálné rozměry variant) assetům, kterým chybí (meta IS NULL) — tj. nahraným před zavedením meta sloupce jednorázově po nasazení, pak už netřeba
/cron/system/asset-variant-regenerate/default Dogenerování chybějících variant uložených obrázků : totéž co tlačítko „Dogenerovat" na záložce Použití, jen pro VŠECHNA použití najednou po nasazení opakovaně, dokud odpověď neříká remaining: 0; pak stačí denně v noci
/cron/system/auth-log/purge-old Periodický cleanup persistentního audit logu (cms_system_auth_log) denně —
/cron/system/dropzone-temp/clean Úklid dočasných složek dropzone (temp/dropzone) — soubory a prázdné složky starší než 24 h denně
/cron/system/elastic/status Health ES clusteru + počty dokumentů per index — monitoring / smoke check ručně (kontrola stavu)
/cron/system/elastic/watch Hlídá dostupnost vyhledávání a hlásí problémy e-mailem à 15 minut
/cron/system/email-queue/send Postupné odeslání emailů z fronty à minutu
/cron/system/email-queue/purge-old Úklid vyřízených e-mailů (odeslané/zastavené) starších než N dní, newsletterové řádky zůstávají denně
/cron/system/file-system/sanitize Cron pro sanitizaci názvů souborů/složek v uploads adresáři — projde celý strom a přejmenuje položky s nevyhovujícím názvem (diakritika, mezery, nepovolené znaky) na bezpečný tvar ručně, po hromadném nahrání souborů (není periodická)
/cron/system/jwt-deny-list/cleanup-expired Cleanup expirovaných řádků z cms_system_jwt_denylist (DB-backed JtiDenyList) denně v noci (při useRedis: true je to no-op)
/cron/system/log/purge-old Retence adresáře log/ denně
/cron/system/notification/clean-orphans Odpojení osiřelých admin notifikací od cíle (cílový záznam — objednávka, uživatel, platba… — už neexistuje): notifikace se NEMAŽE, jen se vynuluje odkaz na cíl (id), rozhodnutí 1 průchodu administrace denně
/cron/system/notification/purge-read Odpojení osiřelých admin notifikací od cíle (cílový záznam — objednávka, uživatel, platba… — už neexistuje): notifikace se NEMAŽE, jen se vynuluje odkaz na cíl (id), rozhodnutí 1 průchodu administrace denně
/cron/system/page-tree/rebuild Regeneruje nested-set indexy (lft, rgt, level) stromu stránek v cms_system_pages z adjacency (parent_id) ručně, po hromadné změně stromu stránek (není periodická)
/cron/system/payment/activation-audit Sonda „zaplaceno, ale neaktivováno" — platba je COMPLETED, ale položky modulu nejsou aktivní (pád uprostřed callbacku nebo neúspěch handleru) každých 15 minut
/cron/system/payment/purge-notifications Payment maintenance jobs: the activation audit and the retention of the gateway notification history every 15 minutes
/cron/system/rate-limit/purge-old Cleanup expirovaných řádků z cms_system_rate_limit (DB-backed RateLimit) denně v noci (při useRedis: true je to no-op)
/cron/system/scheduler/run Plánovač cronu — jediná adresa, kterou musí hosting volat každých 5 minut (jediná adresa, kterou hosting volá)
/cron/system/sitemap/generate Vygeneruje XML sitemapu pro System stránky se všemi jazykovými variantami (hreflang) denně v noci
/cron/system/sitemap/index Vygeneruje sitemap index (rozcestník) odkazující na všechny vygenerované sitemap- .xml soubory v adresáři denně v noci, AŽ PO ostatních sitemapách
/cron/system/user/anonymize-deleted Account deletion — anonymizes the accounts whose grace period (account.deletion.graceDays, default 7 days) has passed daily
/cron/system/user-refresh-token/purge-old Periodický cleanup expirovaných refresh tokenů (cms_system_user_refresh_tokens) denně

Nastavení cookies