bitrix-background-jobs
CAgent, addBackgroundJob, Messenger brokers/queues. Use for deferred and async processing.
Install
npx skills add https://github.com/bxmaximum/bitrix-framework-skills/tree/main/skills/bitrix-background-jobs
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install bxmaximum-bitrix-framework-skills@llmmart
git clone https://github.com/bxmaximum/bitrix-framework-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole bxmaximum/bitrix-framework-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Background Tasks in Bitrix
Baseline: main 23.0+. Features newer than baseline are marked Since.
Progressive disclosure: open only the rule files that match the task. Do not read every rules/*.md.
How to use
- Identify the layer the task touches.
- Open the matching
rules/*.mdbelow. - Prefer framework-native Bitrix patterns over custom abstractions.
Choose a rule file
When to read rules/agents.md
Read rules/agents.md (CAgent agents) when the task involves:
- Agents (
CAgent)
When to read rules/background-job.md
Read rules/background-job.md (Application::addBackgroundJob) when the task involves:
Application::addBackgroundJob()
When to read rules/messenger.md
Read rules/messenger.md (Messenger queues) when the task involves:
- Messenger (Message Queues)
- When to Choose What
- Checklist
Checklist
- Opened only the rule file(s) needed for this task.
- Followed DI /
/local// security canons fromAGENTS.md.
Files (bitrix-framework-skills)
-
rules
-
agents.md 2.3 KB
# CAgent agents ## Agents (`CAgent`) ```php \CAgent::AddAgent( name: \Vendor\Module\Cli\Agent\QueueAgent::class . '::run();', module: 'vendor.module', period: 'N', // 'Y' — periodic (always by interval), 'N' — shift next_exec interval: 300, // seconds datecheck: '', active: 'Y', next_exec: '', sort: 100, existError: true, ); ``` Agent method: ```php namespace Vendor\Module\Cli\Agent; final class QueueAgent { public static function run(): string { \Bitrix\Main\Loader::includeModule('vendor.module'); \Bitrix\Main\DI\ServiceLocator::getInstance() ->get(\Vendor\Module\Application\Service\QueueProcessor::class) ->processBatch(limit: 100); return self::class . '::run();'; // important: return string for re-registration } } ``` ### Rules - An agent works either on hits or via cron (Admin Panel → Agent Settings). - For heavy agents **always** enable cron — otherwise they block user hits. - An agent running longer than 10 minutes is blocked by the kernel. - Periodic (`period = 'Y'`) vs non-periodic (`period = 'N'`) agents differ in how `next_exec` is calculated. - In module's `DoUninstall`: `CAgent::RemoveModuleAgents('vendor.module')`. - Do not keep state in statics between calls — the process may change. - Combine `addBackgroundJob` for immediate post-response work with `CAgent` for scheduled retries. ### Multisite Agents are shared across the whole installation: stored in one database, executed from one common list, with no filtering by site. An agent does not run per site and gets no user/site context. - Never rely on `SITE_ID` (or any current-site/user context) inside an agent function. - If the logic is site-specific, pass the site ID explicitly in the agent call: `\Vendor\Module\Cli\Agent\SyncAgent::class . "::run('s2');"` — one registered agent per site if needed. - When moving agents to cron, do **not** create identical cron jobs per site — cron runs the shared agent list and cannot inject a site context. ### One-time task for "in 5 minutes" ```php \CAgent::AddAgent( \Vendor\Module\Cli\Agent\SendEmailAgent::class . "::run({$userId});", 'vendor.module', 'N', 60, '', 'Y', (new \Bitrix\Main\Type\DateTime())->add('+5 minutes')->toString(), ); ``` -
background-job.md 1002 B
# Application::addBackgroundJob ## `Application::addBackgroundJob()` Deferred call **after** sending the response (before `fastcgi_finish_request` / in `onAfterEpilog`). Ideal for metrics, welcome emails, or other short tail work. Signature: `addBackgroundJob(callable $job, array $args = [], $priority = Application::JOB_PRIORITY_NORMAL)`. Priorities: | Constant | Value | | --- | --- | | `Application::JOB_PRIORITY_NORMAL` | `100` | | `Application::JOB_PRIORITY_LOW` | `50` | ```php use Bitrix\Main\Application; Application::getInstance()->addBackgroundJob( static function () use ($userId): void { \Vendor\Module\Application\Service\Notifier::fromContainer()->sendWelcome($userId); }, [], Application::JOB_PRIORITY_NORMAL, ); ``` ### Constraints - Still a single PHP process. Long tasks degrade worker release time. - No delivery guarantee: if the process crashes — the task won't execute. - Not suitable if retries and parallelism are needed — use `Messenger`. -
messenger.md 7.6 KB
# Messenger queues ## Messenger (Message Queues) > **Alpha status** (**Since main 25.100.300**): API may change without backward compatibility guarantees. Use with caution in production. Queue = logical channel from sender to handler. Message → broker → receiver processes it. Components: **message** (DTO), **handler** (`AbstractReceiver`), **broker** (storage), **queue** (named handler binding). ### 1. Message (DTO) ```bash php bitrix/bitrix.php make:message SendWelcomeEmail -m vendor.module ``` ```php namespace Vendor\Module\Public\Message; use Bitrix\Main\Messenger\Entity\AbstractMessage; use Bitrix\Main\Messenger\Entity\MessageInterface; final class SendWelcomeEmailMessage extends AbstractMessage { public function __construct( public readonly int $userId, public readonly string $email, ) {} public static function createFromData(array $data): MessageInterface { return new self(...$data); } } ``` Requirements: - JSON-serializable data only: `string`, `int`, `float`, `bool`, `array`. - Implement `jsonSerialize()` for complex structures. - Include all data needed at processing time (entity may be deleted before delayed handling). ### 2. Handler ```bash php bitrix/bitrix.php make:messagehandler SendWelcomeEmail \ --message-module=vendor.module --handler-module=vendor.module ``` (`make:messagehandler` uses **`--message-module`**, not `--event-module`. The latter belongs to `make:eventhandler`.) ```php namespace Vendor\Module\Internals\Messenger\Receiver; use Bitrix\Main\Messenger\Entity\MessageInterface; use Bitrix\Main\Messenger\Receiver\AbstractReceiver; use Bitrix\Main\Messenger\Internals\Exception\Receiver\UnprocessableMessageException; use Vendor\Module\Public\Message\SendWelcomeEmailMessage; final class SendWelcomeEmailHandler extends AbstractReceiver { public function __construct( private readonly \Vendor\Module\Application\Service\Mailer $mailer, ) { parent::__construct(); } protected function process(MessageInterface $message): void { if (!$message instanceof SendWelcomeEmailMessage) { throw new UnprocessableMessageException($message); } $this->mailer->sendWelcome($message->userId, $message->email); } } ``` **Handler MUST be registered in module `services`** — `QueueConfig::createReceiver()` resolves it via `ServiceLocator::get($handler)`: ```php // /local/modules/vendor.module/.settings.php 'services' => [ 'value' => [ \Vendor\Module\Internals\Messenger\Receiver\SendWelcomeEmailHandler::class => [ 'className' => \Vendor\Module\Internals\Messenger\Receiver\SendWelcomeEmailHandler::class, ], // or constructor closure / autowire as usual ], 'readonly' => true, ], ``` Handler rules: - Extend `AbstractReceiver`, implement **`protected function process()`** (not `handle()`). - Return `void` on success; throw on failure. - Exception types (namespace `Bitrix\Main\Messenger\Internals\Exception\Receiver\`): - `UnprocessableMessageException` — wrong message type (`__construct(MessageInterface $messengerMessage, ...)`) - `UnrecoverableMessageException` — no retry - `RecoverableMessageException` — temporary, optional `getRetryDelay()` ### 3. Dispatching ```php $message = new SendWelcomeEmailMessage($userId, $email); $message->send('vendor_module_queue'); // Delayed processing (1 hour): use Bitrix\Main\Messenger\Entity\ProcessingParam\DelayParam; use Bitrix\Main\Messenger\Entity\ProcessingParam\ItemIdParam; $message->send('vendor_module_queue', [ new DelayParam(3600), new ItemIdParam('welcome-' . $userId), ]); ``` Do **not** use `MessageBus::dispatch()` — the current API is `$message->send('queue_name')`. ### 4. Configuration in `.settings.php` Global config (`/bitrix/.settings.php` or `/local/.settings.php`) — brokers and cross-module queues: ```php 'messenger' => [ 'value' => [ 'run_mode' => 'web', // 'web' — background jobs on hit; 'cli' — requires messenger:consume 'brokers' => [ 'default' => [ 'type' => 'db', 'params' => [ 'table' => \Bitrix\Main\Messenger\Internals\Storage\Db\Model\MessengerMessageTable::class, ], ], ], 'queues' => [ 'vendor_module_queue' => [ 'handler' => \Vendor\Module\Internals\Messenger\Receiver\SendWelcomeEmailHandler::class, ], ], ], 'readonly' => true, ], ``` Module config (`/local/modules/vendor.module/.settings.php`) — module-specific queues: ```php 'messenger' => [ 'value' => [ 'queues' => [ 'vendor_module_queue' => [ 'handler' => \Vendor\Module\Internals\Messenger\Receiver\SendWelcomeEmailHandler::class, 'limit' => 10, // messages per batch (default 50) 'total_processing_limit' => 50, // max concurrent, default 100; must be >= limit (else ArgumentOutOfRangeException at consume) 'retry_strategy' => [ 'max_retries' => 3, 'delay' => 5, 'multiplier' => 2, 'max_delay' => 300, ], ], ], ], 'readonly' => true, ], ``` Notes: - Only broker type **`db`** is supported currently (not Redis/Doctrine DSN). - The `default` broker must always exist in global config. - Put queues in the module `.settings.php` they belong to; global config only for cross-module queues. - Custom broker table: extend `MessengerMessageTable`, register in `brokers`, create table in module installer. - Queue `handler` FQCN must also exist under module `services` (see above). - `limit` default **50**, `total_processing_limit` default **100**. Consume throws `ArgumentOutOfRangeException` if `limit > total_processing_limit`. ### 5. Consumer (CLI mode) Set `'run_mode' => 'cli'` and run under Supervisor/systemd: ```bash php bitrix/bitrix.php messenger:consume vendor_module_queue \ --time-limit=300 --sleep=1 ``` Flags: - `-t, --time-limit` — process lifetime in seconds. - `--sleep` — pause between iterations when queue is empty (default 1). Queue names are separate CLI arguments (`messenger:consume q1 q2`), not a comma-separated string. There is **no** `--limit` option in main 26.650.100 (it is commented out in `ConsumeMessagesCommand`); set `limit` / `total_processing_limit` on the queue in `.settings.php`. For production with heavy queues, prefer `cli` mode with a supervisor over `web` mode. ## When to Choose What - **Periodic task by schedule** → `CAgent` + cron mode. - **"Almost instant" tail after response** (email notification, metric) → `addBackgroundJob`. - **Reliable processing with retries, high volumes, parallelism** → `Messenger` (**Since 25.100.300**, alpha). - **Very long one-time data migration** → console command run manually. ## Checklist - [ ] Background code does not rely on `$_SESSION`/`$_COOKIE` in the hit context. - [ ] Agents registered by the module are removed in `DoUninstall`. - [ ] For CLI queues, `time-limit`, supervisor restart, and `run_mode=cli` are configured. - [ ] Messages contain scalars/DTOs with all data needed at processing time; no `EntityObject` with loaded relations. - [ ] Handler is registered in `services` and is idempotent: re-processing the same message is safe. - [ ] `total_processing_limit` >= `limit` in queue config. - [ ] Errors inside tasks are logged via PSR-3 logger, not silently suppressed. - [ ] `addBackgroundJob` uses `JOB_PRIORITY_NORMAL` (100) / `JOB_PRIORITY_LOW` (50), not arbitrary `0`.
-
-
SKILL.md 1.1 KB
--- name: bitrix-background-jobs description: CAgent, addBackgroundJob, Messenger brokers/queues. Use for deferred and async processing. --- # Background Tasks in Bitrix Baseline: **main 23.0+**. Features newer than baseline are marked **Since**. Progressive disclosure: open **only** the rule files that match the task. Do not read every `rules/*.md`. ## How to use 1. Identify the layer the task touches. 2. Open the matching `rules/*.md` below. 3. Prefer framework-native Bitrix patterns over custom abstractions. ## Choose a rule file ### When to read `rules/agents.md` Read `rules/agents.md` (`CAgent agents`) when the task involves: - Agents (`CAgent`) ### When to read `rules/background-job.md` Read `rules/background-job.md` (`Application::addBackgroundJob`) when the task involves: - `Application::addBackgroundJob()` ### When to read `rules/messenger.md` Read `rules/messenger.md` (`Messenger queues`) when the task involves: - Messenger (Message Queues) - When to Choose What - Checklist ## Checklist - [ ] Opened only the rule file(s) needed for this task. - [ ] Followed DI / `/local/` / security canons from `AGENTS.md`.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.