Comment utiliser la capacité d'exécution simultanée de Drush?

9

J'utilise plusieurs sites Drupal (base de code unique, plusieurs sites / *). Parallèlement à cela, j'ai commencé à utiliser des alias Drush pour les gérer:

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

Cela me permet d'effectuer facilement des actions sur tous les sites:

$ drush @localdev cc all

>> Je viens également de découvrir que je peux simplement utiliser @sites et renoncer au fichier drushrc .

Ce faisant, exécutera "cc all" sur chacun de mes sites en série (un à la fois).

Je voudrais prendre cela au niveau suivant et essayer d'exécuter ces commandes sur tous les sites de manière simulatrice . J'ai fait quelques lectures et j'ai l'impression que Drush soutient effectivement cela. La fonction drush_invoke_process () prend $ backend_options, qui peut contenir (à partir de la documentation de la fonction):

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

Ce que je ne peux pas comprendre, cependant, est comment utiliser cela à partir de la ligne de commande Drush . Existe-t-il une option que je dois transmettre à Drush, ou dois-je définir quelque chose dans un fichier de paramètres?

Toute information sera très appréciée - ma curiosité est piquée!

MISE À JOUR

Sur la base des réponses ci-dessous, j'ai pu créer un test simple qui démontre le comportement de Drush et tirer quelques conclusions:

Le comportement par défaut de Drush lors de l'exécution d'opérations sur plusieurs sites consiste à utiliser des processus simultanés:

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

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

Cela est vrai même lorsque vous n'utilisez pas d'alias, et cela est également vrai lorsque vous utilisez l'alias @sites intégré de Drush. Ces deux commandes donnent un comportement identique à celui ci-dessus:

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

Pour modifier le nombre de processus simultanés (la valeur par défaut est 4), l'option '--concurrency = N' peut être passée dans la commande drush. Par exemple, si je souhaite une exécution en série, je peux définir le nombre de processus simultanés sur 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
la source
C'est un très bon résumé; merci de l'avoir écrit. Ce serait génial si cette information se trouvait quelque part dans la documentation Drush. J'ai ouvert un problème pour capturer cela: drupal.org/node/1914224
greg_1_anderson

Réponses:

5

Cela a fonctionné pour moi:

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

Je ne sais pas à quel point c'était concomitant; le dernier message sur site1 est venu immédiatement après le premier message pour site2, et tous les autres messages ont été imprimés séquentiellement. Je n'ai pas mesuré dans quelle mesure chaque opération cc s'est produite simultanément, ou dans quelle mesure le système aurait pu simplement être lié à l'unité centrale de traitement ou aux E / S, mais il semblait fonctionner nominalement.

greg_1_anderson
la source
Je travaille avec quelque chose de similaire à cela et j'ai réalisé une façon pratique de faire les choses en utilisant la @sitescommande. Cependant, un problème avec cela est que si le répertoire du site est un lien symbolique, la commande ne le reconnaît pas. dans mon cas, le lien symbolique est vers un répertoire extérieur à la racine drupal, donc ls- l donne: site_dir -> ../../sites/site/src.. peut-être que c'est un bug que je peux corriger si vous pouvez me diriger vers le code responsable de la construction de la liste
awm
1

Pour une seule instance (sans liste de sites):

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

Pour les alias avec un tableau de liste de sites, il fonctionnera de manière concurrente même ...

Après les commentaires ci-dessous , passons en revue le code de drush_invoke_process:
//- mon commentaire, /* ... */- raccourcissant le code fourni.

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

Appelé ensuite:

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

Le prochain sera appelé:

<?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
la source
Pouvez-vous clarifier s'il vous plait? Êtes-vous en train de dire que lors de l'utilisation d'une liste de sites, Drush exécutera automatiquement les commandes simultanément sur tous les sites? Je suis confus car un responsable Drush a suggéré que le comportement par défaut est l'exécution en série drupal.org/node/628996#comment-2637008 .
rcourtna
invoke-multiple permet d'exécuter plusieurs fois la même commande sur le même site avec les mêmes options et arguments. Vous voulez --concurrency = N pour exécuter la même commande sur plusieurs sites. C'est l'intention, de toute façon; Je n'ai pas testé avec @sites ou une 'liste de sites', mais vous vous éloignez du comportement prévu, si cela devait arriver.
greg_1_anderson
Vous avez raison sur --concurrency; si vous exécutez une commande sur plusieurs sites en mode débogage sans --concurrency et sans --invoke-multiple, vous pouvez facilement voir qu'elle exécute toutes les commandes simultanément. Mais encore une fois, 'invoke-multiple' => TRUE ne fait rien, et le définir sur 2 dans un alias de site ferait exécuter toutes vos commandes deux fois.
greg_1_anderson
2greg_1_anderson: le paramètre invoke_multiple fonctionnera si vous ne définissez pas d'alias ou de liste de sites ...
Nikit