Magento 2 – Should the Crontab Area Have Its Own di.xml?

configurationcronmagento2object-managerPHP

Does Magento 2's crontab area load a scoped di.xml file? Or is this no longer used? Or should it be used, but its not being loaded as part of the crontab application is a bug? Or do I fundamentally misunderstand something?

In Magento 2, the "areas" feature allows you to load extra configuration information based on the request context (that's a little hand wavy, but accurate from a certain point of view).

For example, Magento will always load the following di.xml

./vendor/magento/module-tax/etc/di.xml

but will only load the following di.xml when in the frontend area

./vendor/magento/module-tax/etc/frontend/di.xml

It's not clear if this is true for the di.xml files for the crontab area.

The cron runner in Magento is a separate Magento System Application from the Magento System Application that handles HTTP requests. When the cron application launches, its Magento System Application has a very minimal launch

#File: vendor/magento/framework/App/Cron.php
public function launch()
{
    $this->_state->setAreaCode('crontab');
    $this->_eventManager->dispatch('default');
    $this->_response->setCode(0);
    return $this->_response;
}

You can see the call to setAreaCode where the crontab area code is set. This ensures that requests for configuration trees will merge in any configuration located in a module's etc/crontab folder

app/etc/crontab/*.xml

Howeverdi.xml is different/special. Because Magento needs access to the object manager earlier than the launch of the Magento system application, the object manager initially loads all the etc/di.xml files before the call to setAreaCode.

During an HTTP request, the Magento System Application (Magento\Framework\App\Http) loads the area specific di.xml files after setting the area code

#File: vendor/magento/framework/App/Http.php
public function launch()
{
    $areaCode = $this->_areaList->getCodeByFrontName($this->_request->getFrontName());
    $this->_state->setAreaCode($areaCode);
    $this->_objectManager->configure($this->_configLoader->load($areaCode));
    //...
}

Since this call to configure is missing from the cron Application's launch method, it seems like the crontab doesn't load any etc/crontab/di.xml files. However, there are a few etc/crontab/di.xml files present.

$ find . -wholename '*crontab/di.xml'
./vendor/magento/module-captcha/etc/crontab/di.xml
./vendor/magento/module-catalog-rule-configurable/etc/crontab/di.xml

This creates some confusion about what the correct behavior of the system should be. Has anyone here been following Magento 2 development closely enough to know what the correct system behavior is?

Best Answer

Based on feedback from the core team, it sounds like the current behavior is not the intended behavior, and in future versions the crontab application will load in a crontab area's di.xml.

Related Topic