如何使用Drush的并发执行功能?


9

我正在使用Drupal多站点(单个代码库,多个站点/ *)。与此同时,我已经开始使用Drush别名来管理它们:

$ cat sites/all/drush/aliases.drushrc.php
<?php
$aliases['localdev'] = array(
  'site-list' => array(
    'site1', 
    'site2',
    'site3',
  ),
);
?>

这使我可以轻松地在所有站点上执行操作:

$ drush @localdev cc all

>> 我还发现我可以只使用@sites,而放弃drushrc文件

这样做,将在我的每个系列站点(一次一个)中执行“ cc all”。

我想借此到一个新的水平,并尝试在所有网站上运行这些命令simulantiously。我一直在做一些阅读,和上午的印象是Drush 确实支持这一点。该drush_invoke_process()函数需要$ backend_options,它可以包含(从函数文档):

 *      'invoke-multiple'
 *        If $site_alias_record represents a single site, then 'invoke-multiple'
 *        will cause the _same_ command with the _same_ arguments and options
 *        to be invoked concurrently (e.g. for running concurrent batch processes).
 *      'concurrency'
 *        Limits the number of concurrent processes that will run at the same time.
 *        Defaults to '4'.

但是,我不知道是如何从Drush命令行实际使用它。是否需要传递给Drush的选项,还是需要在设置文件中进行设置?

任何信息将不胜感激-我的好奇心激起!

更新

根据以下答案,我能够创建一个简单的测试来演示Drush的行为,并得出一些结论:

在多个站点上执行操作时,Drush的默认行为是使用并发进程:

$ drush @localdev ev "drupal_set_message(time()); sleep(5);"

Continue?  (y/n): y
site1             >> 1360512943      [status]
site2             >> 1360512943      [status]
site3             >> 1360512943      [status]

即使不使用别名也是如此,而在使用Drush的内置@sites别名时也是如此。这两个命令产生与上述相同的行为:

$ drush site1,site2,site3 ev "drupal_set_message(time()); sleep(5);"
$ drush @sites ev "drupal_set_message(time()); sleep(5);"

要更改并发进程数(默认为4),可以在drush命令中传递'--concurrency = N'选项。例如,如果要串行执行,可以将并发进程数设置为1:

$ drush @localdev ev "drupal_set_message(time()); sleep(5);" --concurrency=1

Continue?  (y/n): y
site1             >> 1360513387      [status]
site2             >> 1360513393      [status]
site3             >> 1360513399      [status]

这是一个很好的总结;感谢您编写它。如果该信息在Drush文档中的某个位置,那将是很好的。我打开一个问题来捕捉这一点:drupal.org/node/1914224
greg_1_anderson

Answers:


5

这为我工作:

drush @site1,@site2,@site3,@site4 cc all --concurrency=4

我不确定它实际上是如何并发的。关于site1的最后一条消息紧接在site2的第一条消息之后,所有其他消息均按顺序打印。我没有测量每个cc操作并发发生的程度,也没有衡量系统可能刚刚被cpu或I / O约束的程度,但是它似乎确实可以正常工作。


我正在使用与此类似的东西,并实现了使用该@sites命令的便捷方法。但是,与此有关的一个小问题是,如果站点目录是符号链接,则该命令无法识别它。在我的情况下,符号链接是在drupal根目录之外的一个目录,因此ls- l给出了site_dir -> ../../sites/site/src..如果您能将我指向负责建立列表的代码,我可以解决这个错误
awm

1

对于单个实例(无站点列表):

<?php
$aliases['localdev'] = array(
  'invoke-multiple' => TRUE,
);
?>

对于带有站点列表数组的别名,它甚至可以同时运行...

在下面的注释之后,让我们回顾一下drush_invoke_process的代码:
//-我的注释,/* ... */-缩短提供的代码。

<?php
function drush_invoke_process($site_alias_record, $command_name, $commandline_args = array(), $commandline_options = array(), $backend_options = TRUE) {
  if (is_array($site_alias_record) && array_key_exists('site-list', $site_alias_record)) {
    /*  $invocations[] - this array filled with command for each site in site-list. */
  }
  else {
    /* aliases not defined or site-list not found.  So $invocations filled by one item. */
  }
  return drush_backend_invoke_concurrent($invocations, $commandline_options, $backend_options);
}
?>

接下来称为:

<?php
function drush_backend_invoke_concurrent($invocations, $common_options = array(), $common_backend_options = array(), $default_command = NULL, $default_site = NULL, $context = NULL) {
  /* Here building command line happen for each site (invocation). */
  return _drush_backend_invoke($cmds, $common_backend_options, $context);
}
?>

接下来将调用:

<?php
function _drush_backend_invoke($cmds, $common_backend_options = array(), $context = NULL) {
  /* Some simulating code and fork code */
  if (array_key_exists('interactive', $common_backend_options) || array_key_exists('fork', $common_backend_options)) {
    /* Direct running (interactive or fork) */
  }
  else {
    // Concurrency set to 4 by default. So --concurency just override it by another value.
    $process_limit = drush_get_option_override($common_backend_options, 'concurrency', 4);

    // Next is main call, that run commands as concurent processes using proc_open and streaming:
    $procs = _drush_backend_proc_open($cmds, $process_limit, $context);

    /* Processing of result running of processes. */

  }
  return empty($ret) ? FALSE : $ret;
}
?>

你能澄清一下吗?您是说在使用站点列表时,Drush会在所有站点上自动并发执行命令吗?我很困惑,因为Drush维护者建议默认行为是串行执行drupal.org/node/628996#comment-2637008
rcourtna

invoke-multiple用于在同一站点上使用相同的选项和参数多次运行同一命令。您希望--concurrency = N在多个站点上运行同一命令。无论如何,这就是意图。我没有使用@sites或“站点列表”进行测试,但是如果这样做确实可行,那么您将偏离预期的行为。
greg_1_anderson

您对--concurrency是正确的;如果您在多个调试站点上以--concurrency和--invoke-multiple方式运行命令,则很容易看到该命令正在同时运行所有命令。但是同样,'invoke-multiple'=> TRUE不会执行任何操作,并且在站点别名中将其设置为2会使您的所有命令运行两次。
greg_1_anderson

2greg_1_anderson:如果您不设置别名或站点列表,则invoke_multiple设置将起作用...
Nikit 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.