【问题标题】:Accessing the Zend Application Bootstrap _init Functions After Bootstrapping引导后访问 Zend 应用程序引导 _init 函数
【发布时间】:2011-06-13 13:28:36
【问题描述】:

我为并行任务编写了一个基于 Zend Framework 的 cron 服务,ran into issues with the child threads sharing resources with the parent。我解决了database connection issue,但我现在看到Zend_Db_Table_Abstract 无法将表元数据保存到元数据缓存的周期性问题。

将元数据保存到 metadataCache 失败

我在引导期间初始化元数据缓存。与其从引导程序复制我的代码并在分叉后执行,我认为使用$application->bootstrap('[...]') 调用Bootstrap->_init[...] 函数可能会更好。


更新

因为Zend_Controller_Front::getInstance() 是一个单例,使用它来获取引导实例并以这种方式调用函数会使我回到我已经解决的共享资源的相同问题。

我想以某种方式保持这个 DRY,同时避免分叉后共享资源的问题。

【问题讨论】:

    标签: php zend-framework zend-application zend-app-bootstrap


    【解决方案1】:

    Zend_Controller_Front Singleton 包含一个引导程序实例

    $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
    $bootstrap->bootstrap('db')
    

    【讨论】:

    • 感谢本杰明!我试了一下,但发现使用Zend_Controller_Front Singleton 继续与父线程共享,我再次收到“一般错误:2006 MySQL 服务器已消失”。
    • 请为此打开另一个问题。当前问题应按原样回答。PHP 手册中的此评论可能会帮助您解决分叉问题:php.net/manual/en/function.pcntl-fork.php#70721
    • 我链接到的原始线程解决了这个问题。我目前的问题是关于代码重用。 Zend_Controller_Front::getInstance() 的单例行为阻止了它在分叉场景中的使用。我会澄清这个问题。
    【解决方案2】:

    Zend_Controller_Front 是单例的,但它的构造函数是受保护的,所以你可以简单地通过创建一个名为 App_Controller_Front 的类来扩展它

    在其中为 getNewInstance() 创建一个方法,该方法可以调用构造函数而不检查是否存在。这样您就可以覆盖单例行为。

    【讨论】:

    • 这似乎是我必须走的路。我会试试看。谢谢!
    • 我现在会接受这个作为答案,但仍然需要测试它。
    【解决方案3】:

    您不是使用 pcntl_fork 来“分叉”这些并行进程,而是通过您的 crobjob 多次运行它们,对吗?这意味着它们作为彼此独立的进程运行,唯一的共享资源(以及后续冲突)是系统资源(尤其是文件)。

    您看到的错误可能是由与正在写入缓存的文件相关的任意数量的事情引起的。例如,如果元数据文件被您的另一个进程锁定,您可能会看到该错误,直到您正在运行的并行进程数量非常多时才会出现该问题。

    当元数据缓存文件由于其他原因无法写入时也会出现该错误,例如它所在的分区磁盘空间不足或文件权限设置不正确。

    也许您可以详细说明如何配置元数据缓存以及脚本并行化的工作方式。另外,您运行的是哪个版本的 Zend Framework?

    【讨论】:

    • 我确实是在用 pcntl_fork 进行分叉。我链接到的关于解决我的数据库连接问题的线程包含所有这些信息。不过,您可能对缓存写入错误是正确的。我已经有一段时间没有看到错误了。无论如何,我想让我的应用程序保持干燥。
    【解决方案4】:

    为什么每个子线程都读取配置、缓存数据库元数据等?使用主/从层次结构。共同点:

    $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); 
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多