Como usar a capacidade de execução simultânea do Drush?

9

Estou usando vários sites do Drupal (base de código única, vários sites / *). Junto com isso, comecei a usar aliases Drush para gerenciá-los:

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

Isso me permite executar ações facilmente em todos os sites:

$ drush @localdev cc all

>> Eu também só descobri que eu posso usar apenas @sites , e renunciar o arquivo drushrc .

Fazendo isso, executará "cc all" em cada um dos meus sites em série (um de cada vez).

Eu gostaria de levar isso para o próximo nível e tentar executar esses comandos em todos os sites de forma simultânea . Eu tenho feito algumas leituras, e estou sob a impressão de que Drush se de fato suportar isto. A função drush_invoke_process () aceita $ backend_options, que pode conter (da documentação da função):

 *      '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'.

O que não consigo descobrir, no entanto, é como realmente utilizo isso na linha de comando Drush . Existe uma opção que preciso passar para o Drush ou preciso definir algo em um arquivo de configurações?

Qualquer informação será muito apreciada - minha curiosidade é aguçada!

ATUALIZAR

Com base nas respostas abaixo, pude criar um teste simples que demonstra o comportamento de Drush e tirar algumas conclusões:

O comportamento padrão do Drush ao executar operações em vários sites é usar processos simultâneos:

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

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

Isso acontece mesmo quando não se usa aliases, e também quando se usa o alias incorporado @sites do Drush. Esses dois comandos geram um comportamento idêntico ao descrito acima:

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

Para alterar o número de processos simultâneos (o padrão é 4), a opção '--concurrency = N' pode ser passada no comando drush. Por exemplo, se eu quiser execução em série, posso definir o número de processos simultâneos como 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]
rcourtna
fonte
Esse é um resumo muito bom; obrigado por escrevê-lo. Seria ótimo se essas informações estivessem na documentação do Drush em algum lugar. Abri uma questão a captura que: drupal.org/node/1914224
greg_1_anderson

Respostas:

5

Isso funcionou para mim:

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

Não tenho certeza de quão simultâneo foi realmente; a última mensagem sobre o site1 veio imediatamente após a primeira mensagem para o site2 e todas as outras mensagens foram impressas sequencialmente. Não medi até que ponto cada operação cc ocorreu simultaneamente ou em que medida o sistema poderia ter sido cpu ou i / o ligado, mas parecia estar funcionando nominalmente.

greg_1_anderson
fonte
Estou trabalhando com algo semelhante a isso e percebi uma maneira prática de fazer as coisas usando o @sitescomando No entanto, uma falha é que, se o diretório do site for um link simbólico, o comando não o reconhecerá. no meu caso o link simbólico é uma raiz dir fora drupal tão LS- l dá: site_dir -> ../../sites/site/src.. Talvez seja bug posso corrigir se você pode me apontar para o código responsável de thelist construção
awm
1

Para instância única (sem lista de sites):

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

Para aliases com o array da lista de sites, ele será executado de forma simultânea ...

Após os comentários abaixo , vamos revisar o código para drush_invoke_process:
//- meu comentário, /* ... */- encurtando o código fornecido.

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

Em seguida chamado:

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

Em seguida será chamado:

<?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;
}
?>
Nikit
fonte
Você pode esclarecer por favor? Você está dizendo que, ao usar uma lista de sites, o Drush executará automaticamente os comandos simultaneamente em todos os sites? Estou confuso porque um mantenedor do Drush sugeriu que o comportamento padrão é a execução em série drupal.org/node/628996#comment-2637008 .
Rcourtna
invoke-multiple é para executar o mesmo comando no mesmo site com as mesmas opções e argumentos várias vezes. Você deseja --concurrency = N para executar o mesmo comando em vários sites. Essa é a intenção, de qualquer maneira; Não testei com @sites ou com uma 'lista de sites', mas você está se afastando do comportamento pretendido, caso isso funcione.
Greg_1_anderson
Você está correto sobre --concurrency; se você executar um comando em vários sites no modo de depuração sem --concurrency e sem --invoke-multiple, poderá ver facilmente que ele está executando todos os comandos simultaneamente. Mas, novamente, 'invoke-multiple' => TRUE não faz nada, e defini-lo como 2 em um alias de site faria todos os seus comandos serem executados duas vezes.
Greg_1_anderson
2greg_1_anderson: a configuração invoke_multiple funcionará se você não definir alias ou lista de sites ...
Nikit