젠장, 나는 약간의 역설을 좋아하지만 , 특히 대기열이 실행 될 경우 작업 매개 변수 와 영역 ( adminhtml | crontab | frontend | global | install )을 대기열 로 전송하는 복잡성 / 취성에 동의하지 않아야합니다 마 젠토 컨텍스트. 처리해야하는 혼합 컨텍스트가있는 경우 큐 솔루션은 현재 "문제"를 다시 구현 한 것입니다!
대기열 접근 방식이 취 약하다고 생각합니다. 내 주장은 이벤트 영역을 조기에로드하는 것이 실제로 문제가되지 않는다는 것입니다. 이를 설명하기 위해 백업하고 문제를 살펴 보자.
실행 범위에서 이벤트 영역을 조기에로드하면 어떤 위험이 있습니까?
이를 이해하려면 실행 컨텍스트에서 이벤트 영역을 조사해야합니다. 마티아스, 나는 당신이 이미 이것을 알고 있지만 다른 사람들의 교화를 위해 상상합니다.
Mage_Core_Model_App::run()
요청을 프론트 컨트롤러로 디스패치하기 전에 데이터 설정 스크립트가 실행됩니다 .
public function run($params)
{
$options = isset($params['options']) ? $params['options'] : array();
$this->baseInit($options);
Mage::register('application_params', $params);
if ($this->_cache->processRequest()) {
$this->getResponse()->sendResponse();
} else {
$this->_initModules();
//Global event area is loaded here
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
if ($this->_config->isLocalConfigLoaded()) {
$scopeCode = isset($params['scope_code']) ? $params['scope_code'] : '';
$scopeType = isset($params['scope_type']) ? $params['scope_type'] : 'store';
$this->_initCurrentStore($scopeCode, $scopeType);
$this->_initRequest();
//Data setup scripts are executed here:
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
}
$this->getFrontController()->dispatch();
}
return $this;
}
데이터 설정 스크립트가 실행될 때까지 전역 이벤트 영역이로드됩니다. 라우팅 컨텍스트 컨텍스트 이벤트 영역 ( frontend 또는 adminhtml )은 Mage_Core_Controller_Varien_Action::preDispatch()
컨트롤러 조치와 일치하는 라우터의 결과로 나중에로드됩니다 ( area
이름은 상속을 통해 설정 됨).
public function preDispatch()
{
//...
Mage::app()->loadArea($this->getLayout()->getArea());
//...
}
따라서 일반적으로 앱을 초기화하는 동안 전역 이벤트 영역 에서 구성된 관찰자 만 실행됩니다. 설정 스크립트가 다음과 같은 작업을 수행하는 경우
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);
다음 두 가지 위험이 있습니다.
- 관찰자가 아래에 잘못 된 adminhtml 컨텍스트없는 이벤트를 관찰 등
controller_front_init_before
또는controller_front_init_routers
- 요청은 프론트 엔드 요청입니다.
# 1은 잡기 쉬워야합니다. # 2는 실제 관심사이며, Reflection이 문제를 해결할 수 있다고 생각합니다 (반사를 사용하는 것이 현명하게 경험이 없다는 것을 유의하십시오).
<?php
//Start setup script as normal
$installer = $this;
$installer->startSetup()
//Load adminhtml event area
Mage::app()->loadAreaPart(
Mage_Core_Model_App_Area::AREA_ADMINHTML,
Mage_Core_Model_App_Area::PART_EVENTS
);
// your setup script logic here
//I hope this isn't a bad idea.
$reflectedApp = new ReflectionClass('Mage_Core_Model_App');
$_areas = $reflectedApp->getProperty('_areas');
$_areas->setAccessible(true);
$areas = $_areas->getValue(Mage::app());
unset($areas['adminhtml']);
$_areas->setValue(Mage::app(),$areas); //reset areas
//End setup script as normal
$installer->endSetup()
나는 이것을 테스트하지는 않았지만 adminhtml 이벤트 색인과 해당 Mage_Core_Model_App_Area
객체를 제거 합니다.