¿Cómo usar la capacidad de ejecución concurrente de Drush?

9

Estoy usando múltiples sitios de Drupal (base de código único, múltiples sitios / *). Junto con esto, comencé a usar alias Drush para administrarlos:

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

Esto me permite realizar acciones fácilmente en todos los sitios:

$ drush @localdev cc all

>> También acabo de descubrir que puedo usar @sites y renunciar al archivo drushrc .

Al hacer esto, ejecutaré "cc all" en cada uno de mis sitios en serie (uno a la vez).

Me gustaría llevar esto al siguiente nivel e intentar ejecutar estos comandos en todos los sitios de forma simultánea . He estado leyendo, y da la impresión de que Drush no de hecho compatible con esta. La función drush_invoke_process () toma $ backend_options, que puede contener (de la documentación de la función):

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

Sin embargo, lo que no puedo entender es cómo puedo usar esto desde la línea de comando Drush . ¿Hay alguna opción que deba pasar a Drush o debo configurar algo en un archivo de configuración?

Cualquier información será muy apreciada, ¡mi curiosidad se despertó!

ACTUALIZAR

Basado en las respuestas a continuación, pude crear una prueba simple que demuestra el comportamiento de Drush, y sacar algunas conclusiones:

El comportamiento predeterminado de Drush al ejecutar operaciones en múltiples sitios es usar procesos concurrentes:

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

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

Esto es cierto incluso cuando no se usan alias, y también es cierto cuando se usa el alias incorporado @sites de Drush. Estos dos comandos producen un comportamiento idéntico al anterior:

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

Para cambiar el número de procesos concurrentes (el valor predeterminado es 4), la opción '--concurrencia = N' se puede pasar en el comando drush. Por ejemplo, si quiero la ejecución en serie, puedo establecer el número de procesos concurrentes en 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
fuente
Ese es un muy buen resumen; Gracias por escribirlo. Sería genial si esa información estuviera en la documentación de Drush en alguna parte. Abrí un problema para capturar eso: drupal.org/node/1914224
greg_1_anderson

Respuestas:

5

Esto funcionó para mí:

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

No estoy seguro de lo concurrente que fue en realidad; el último mensaje sobre el sitio1 llegó inmediatamente después del primer mensaje para el sitio2, y todos los demás mensajes se imprimieron secuencialmente. No medí en qué medida cada operación cc ocurrió simultáneamente, o en qué medida el sistema podría haber sido limitado por CPU o E / S, pero parecía estar funcionando nominalmente.

greg_1_anderson
fuente
Estoy trabajando con algo similar a esto y me di cuenta de una manera práctica de hacer las cosas usando el @sitescomando. Sin embargo, un problema con esto es que si el directorio del sitio es un enlace simbólico, el comando no lo reconoce. en mi caso, el enlace simbólico es a un directorio fuera de la raíz de drupal, así que ls- l da: site_dir -> ../../sites/site/srctal vez es un error que puedo solucionar si me puede señalar el código responsable de construir la lista
awm
1

Para una sola instancia (sin lista de sitios):

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

Para los alias con la matriz de lista de sitios, se ejecutará de forma concisa incluso ...

Después de los comentarios a continuación , revisemos el código para drush_invoke_process:
//- mi comentario, /* ... */- acortando el código proporcionado.

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

Siguiente llamado:

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

A continuación se llamará:

<?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
fuente
¿Puedes por favor aclarar? ¿Estás diciendo que cuando usas una lista de sitios, Drush ejecutará automáticamente los comandos simultáneamente en todos los sitios? Estoy confundido porque un mantenedor de Drush sugirió que el comportamiento predeterminado es la ejecución en serie drupal.org/node/628996#comment-2637008 .
rcourtna
invoke-multiple es para ejecutar el mismo comando en el mismo sitio con las mismas opciones y argumentos varias veces. Desea --concurrency = N para ejecutar el mismo comando en varios sitios. Esa es la intención, de todos modos; No probé con @sites o una 'lista de sitios', pero te estás desviando del comportamiento previsto, en caso de que eso funcione.
greg_1_anderson
Tienes razón sobre --concurrencia; Si ejecuta un comando en varios sitios en modo de depuración sin --concurrencia y sin - invocar-múltiple, puede ver fácilmente que está ejecutando todos los comandos al mismo tiempo. Pero, de nuevo, 'invoke-multiple' => TRUE no hace nada, y establecerlo en 2 en un alias de sitio haría que todos sus comandos se ejecuten dos veces.
greg_1_anderson
2greg_1_anderson: la configuración de invoke_multiple funcionará si no configura el alias o la lista de sitios ...
Nikit