{"result":{"depiction_url":null,"edges":{"subject":{"objects":[{"created":"2026-09-09T13:47:47Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-09T13:47:47Z","object_id":{"id":2566,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_operator","title":"Operator","uri":"https:\/\/zotonic.com\/id\/2566"},"seq":2},{"created":"2026-09-09T13:47:47Z","object_id":{"id":2606,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_scheduled_and_background_work","title":"Scheduled and background work","uri":"https:\/\/zotonic.com\/id\/2606"},"seq":3},{"created":"2026-09-09T13:47:47Z","object_id":{"id":2633,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_background_task","title":"Background task","uri":"https:\/\/zotonic.com\/id\/2633"},"seq":4},{"created":"2026-09-09T13:47:47Z","object_id":{"id":2635,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_module","title":"Module","uri":"https:\/\/zotonic.com\/id\/2635"},"seq":5},{"created":"2026-09-09T13:47:47Z","object_id":{"id":2656,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_schedule","title":"Schedule","uri":"https:\/\/zotonic.com\/id\/2656"},"seq":6}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":1811,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1811"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_module_mod_cron","page_url":{"en":"https:\/\/zotonic.com\/docs\/1811\/mod_cron","x-default":"https:\/\/zotonic.com\/docs\/1811\/mod_cron"},"preview_url":null,"resource":{"version":4055,"pivot_location_lat":null,"title":"mod_cron","is_authoritative":true,"body":"<p>Provides periodic tick notifications and module-defined cron job scheduling.<\/p>\n<p>This module both sends periodic <em>tick<\/em> notifications (which can be observed by modules) and reads each module’s\n<code>-mod_cron_jobs<\/code> attribute to register scheduled jobs at specific intervals.<\/p>\n<h2>tick<\/h2>\n<p>For periodic tasks the system has various periodic tick events. They are named after their interval <em>s<\/em> for seconds, <em>m<\/em>\nfor minutes, and <em>h<\/em> for hours.<\/p>\n<ul><li>tick_1s<\/li><li>tick_1m<\/li><li>tick_10m<\/li><li>tick_15m<\/li><li>tick_30m<\/li><li>tick_1h<\/li><li>tick_2h<\/li><li>tick_3h<\/li><li>tick_4h<\/li><li>tick_6h<\/li><li>tick_12h<\/li><li>tick_24h<\/li><\/ul>\n<h3>Example<\/h3>\n<p>Check something every hour.<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">-include_lib(&quot;kernel\/include\/logger.hrl&quot;).\n\nobserve_tick_1h(tick_1h, Context) -&gt;\n    ?LOG_INFO(&quot;And another hour has passed...&quot;),\n    do_something(Context).\n<\/code><\/pre>\n<p>The return value is ignored.<\/p>\n<p>The <em>tick<\/em> observers are called one by one in a separate process. So a slow handler can delay the other handlers.<\/p>\n<h2><code>-mod_cron_jobs<\/code> Module Attribute<\/h2>\n<p>Modules can define periodic jobs using the module attribute <code>-mod_cron_jobs<\/code>.<\/p>\n<p><code>mod_cron<\/code> reads this attribute from active modules and registers each job with <code>erlcron<\/code>.<\/p>\n<p>Each entry is one of:<\/p>\n<ul><li><code>{RunWhen, {Module, Function, Args}}<\/code><\/li><li><code>{RunWhen, {Module, Function, Args}, JobOpts}<\/code><\/li><\/ul>\n<p>Where:<\/p>\n<ul><li><code>RunWhen<\/code> is an <code>erlcron<\/code> schedule tuple (daily\/weekly\/every\/etc.).<\/li><li><code>{Module, Function, Args}<\/code> is the MFA to call.<\/li><li><code>JobOpts<\/code> are optional <code>erlcron<\/code> job options.<\/li><\/ul>\n<p>Important: <code>mod_cron<\/code> appends the site <code>Context<\/code> as the last argument when calling the MFA, so the target function must\naccept one extra argument.<\/p>\n<h3>Example<\/h3>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">-mod_depends([cron]).\n-mod_cron_jobs([\n    {{weekly, mon, {10, 0, 0}}, {?MODULE, send_weekly_reminders, []}}\n]).\n\nsend_weekly_reminders(Context) -&gt;\n    Events = get_this_weeks_events(Context),\n    send_email_reminders(Events, Context).\n<\/code><\/pre>\n<p>This schedules <code>send_weekly_reminders\/1<\/code> every Monday at 10:00 UTC.<\/p>\n<p>Scheduling syntax is provided by <code>erlcron<\/code>, see:\n<a href=\"https:\/\/hexdocs.pm\/erlcron\/readme.html\">https:\/\/hexdocs.pm\/erlcron\/readme.html<\/a><\/p>\n<h2>Accepted Events<\/h2>\n<p>This module handles the following notifier callbacks:<\/p>\n<ul><li><code>observe_tick_1h<\/code>: Run periodic hourly cron checks and enqueue due jobs.<\/li><\/ul>","slug":"mod_cron","doc_module_config":[],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"fad9e0733cbc961b10fc3160429707b53835ef2eabed1e296491bc1e82899333","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":320,"is_a":["meta","category"],"name":"module","title":"Modules","uri":"https:\/\/test.zotonic.com\/id\/320"},"doc_source_path":"apps\/zotonic_mod_cron\/src\/mod_cron.erl","publication_start":"2023-06-24T08:17:47Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_cron\/src\/mod_cron.erl","pivot_location_lng":null,"doc_source_kind":"module","name":"doc_module_mod_cron","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:37Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_cron","publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"c34f80c7ab6700e5d77ac5730deaae0e4710e159\n","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-19T13:18:15Z","title_slug":"mod_cron"},"uri":"https:\/\/zotonic.com\/id\/1811","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1811"}},"status":"ok"}