我为并行任务编写了一个基于Zend Framework的cron服务,ran into issues with the child threads sharing resources with the parent。我解决了database connection issue,但我现在看到Zend_Db_Table_Abstract
无法将表元数据保存到元数据缓存的定期问题。
无法将元数据保存到metadataCache
我在bootstrap期间初始化元数据缓存。我认为使用Bootstrap->_init[...]
调用$application->bootstrap('[...]')
函数可能会更好,而不是从引导程序中复制代码并在分叉后执行代码。
更新
因为Zend_Controller_Front::getInstance()
是一个Singleton,使用它来获取引导实例并以这种方式调用函数会使我回到与我已经解决的共享资源相同的问题。
我想以某种方式保持这种DRY,同时在分叉后避免共享资源的问题。
答案 0 :(得分:3)
Zend_Controller_Front
Singleton持有你的bootstrap实例
$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$bootstrap->bootstrap('db')
答案 1 :(得分:1)
Zend_Controller_Front是单例,但它的构造函数是受保护的,所以你只需创建一个名为App_Controller_Front的类
就可以扩展它。为getNewInstance()创建一个方法,它可以调用构造函数而不检查是否存在。这样您就可以覆盖单例行为。
答案 2 :(得分:0)
你正在'分叉'这些并行进程不是用pcntl_fork,而只是通过你的crobjob多次运行它们,对吗?这意味着它们作为彼此独立的进程运行,唯一的共享资源(以及后续冲突)是系统资源(尤其是文件)。
您看到的错误可能是由与正在写入缓存的文件相关的任何数量的内容引起的。例如,如果元数据文件被另一个进程锁定,您可能会看到该错误,这个问题在您运行的并行进程数量很高之前可能不会显示。
当元数据缓存文件因其他原因无法写入时也会出现该错误,例如它所在的分区磁盘空间不足或文件权限设置不正确。
也许您可以详细说明如何配置元数据缓存以及脚本并行化的工作原理。另外,你正在运行什么版本的Zend Framework?
答案 3 :(得分:0)
为什么每个子线程都读取配置,缓存数据库元数据等?使用主/工作层次结构。常见的想法:
$pid = pcntl_fork();
if ($pid == -1) {
// Fork failed
exit(1);
} elseif ($pid) {
// We are the parent
// prepare common data, cache it, etc.
} else {
// We are the child
// create new db connection, use cached data
// if there is no data in cache yet - sleep
exit(0);
}