Answers:
这是批处理的工作方式(基于我的理解)
(这是进度栏如何更新“完成的工作”进度的方式。)
首先,批处理创建一个队列,并添加您在批处理数组中定义的所有操作(函数和参数),例如,
$batch = array (
'operations' => array(
array('batch_example_process', array($options1, $options2)),
array('batch_example_process', array($options3, $options4)),
),
'finished' => 'batch_example_finished',
'title' => t('Processing Example Batch'),
'init_message' => t('Example Batch is starting.'),
'progress_message' => t('Processed @current out of @total.'),
'error_message' => t('Example Batch has encountered an error.'),
'file' => drupal_get_path('module', 'batch_example') . '/batch_example.inc',
);
此外,它还分配了一个批次ID,该ID在批次之间是唯一的。
现在,批处理调用逐个声明队列项,并执行使用其中定义的参数定义的功能。
前几天我遇到了使用迁移的超时问题,开始想知道批处理API在内部如何工作。
批处理功能
实现Batch的功能应非常谨慎地注意以下事项,
操作中要处理的项目数,例如
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));
}
限制在一个函数调用中要处理的项目数,例如设置限制,
// For this example, we decide that we can safely process 5 nodes at a time without a timeout.
$limit = 5;
更新流程以进行后处理,例如,
// Update our progress information.
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $node->nid;
$context['message'] = t('Now processing %node', array('%node' => $node->title));
通知批次引擎批次是否完成,
// Inform the batch engine that we are not finished,
// and provide an estimation of the completion level we reached.
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
如果在实现功能中遗漏了上述大部分内容,则这些内容将被照顾到Drupal的Core批处理操作。但是总是最好在实现函数中定义
如果关闭了带有批处理请求的页面,则批处理会停止吗?再次打开相同的网址时,它会重新启动吗?迁移模块有时会继续,但是可能正在使用队列?
是的,理想情况下,它应该重新启动批处理,并且如上所述,它基于您实现的功能。
要解决您的PHP超时问题,请使用M迁移模块中提供的Drush批处理,但是首先要挖掘出迁移的批处理功能,然后尝试对您的处理数据进行分块。
如果关闭了带有批处理请求的页面,则批处理会停止吗?
是的,它将停止。
再次打开相同的网址时,它会重新启动吗?迁移模块有时会继续,但是可能正在使用队列?
正如Dinesh所说,这取决于实现。
您应该使用drush运行迁移,因为
Drush在命令行运行,不受任何时间限制(特别是PHP的max_execution_time不适用)。因此,当您启动通过drush运行的迁移过程时,它只是启动并一直运行直到完成。
通过Web界面运行进程时,适用PHP max_execution_time(通常为30秒,如果不短的话)。因此,对于长时间运行的流程,我们需要使用Batch API,该API管理跨多个请求的流程分解。因此,迁移过程将启动,运行25秒钟左右,然后停止并让Batch API发出新的页面请求,并无限期地重启迁移过程。
因此,了解到为什么Drush更好?
快一点
Batch API会带来很多开销-关闭并重新调用页面请求,迁移过程需要再次通过所有必要的构造函数运行,重新建立数据库连接并重新运行查询等。此外,对于部分导入,还需要选择从上次停止的位置开始-如果已导入前500条源记录,则需要找到第501条记录。取决于您的源格式及其构造方式,这可能会缩放,也可能不会缩放-如果您在SQL源中使用高水位标记,则查询本身可以消除较早的记录,并从您上次中断的地方开始。如果不是,则Migrate需要滚动查看源数据以查找第一个未导入的记录。假设有一个大的XML文件作为您的源,
更可靠
通过浏览器运行迁移会将您的桌面和本地Internet连接添加为故障点。当Batch API移至下一个页面请求时,网络故障,浏览器崩溃,错误的选项卡或窗口意外关闭都可能中断您的迁移。匆忙运行减少了活动部件-消除了桌面和本地Internet连接的因素。
更有帮助
如果在Drush中运行时某些地方出了问题,如果有任何有用的错误消息,您将看到它们。使用Batch API的失败常常被吞没,您所看到的只是完全没用的“ AJAX HTTP请求异常终止。调试信息如下。路径:/ batch?id = 901&op = do StatusText:ResponseText:ReadyState:4”。
您可以在此处找到更多信息。
同时,如果即使关闭浏览器窗口也要运行批处理,请考虑使用“ 后台进程”模块。它有一个完成该功能的子模块Background Batch。
该模块将接管现有的Batch API,并在后台进程中运行批处理作业。这意味着,如果您退出批处理页面,则作业将继续,并且您可以稍后返回进度指示器。