2012-01-26 6 views
8

He encontrado este problema varias veces, y no puedo encontrar ninguna solución, sino trivial (ver a continuación).Método seguro para actualizar paquetes R: ¿es posible el intercambio en caliente?

Supongamos que una computadora está ejecutando más de 2 instancias de R, debido a más de 2 usuarios o 1 usuario que ejecuta procesos múltiples, y una instancia ejecuta update.packages(). He tenido varias ocasiones en las que la otra instancia puede ser criticada a lo grande. Los paquetes que se actualizan no cambian la funcionalidad de ninguna manera que afecte el cálculo, pero de alguna manera surge un gran problema.

La solución trivial (Solución 0) es terminar todas las instancias de R mientras se ejecuta update.packages(). Esto tiene más de 2 problemas. Primero, uno tiene que terminar instancias R En segundo lugar, es posible que ni siquiera se pueda identificar dónde se están ejecutando esas instancias (ver actualización 1).

Suponiendo que el comportamiento del código que se está ejecutando no cambiará (por ejemplo, las actualizaciones de paquetes son beneficiosas; solo corrigen errores, mejoran la velocidad, reducen la RAM y otorgan unicornios), ¿hay alguna manera de intercambiar en caliente un nueva versión del paquete con menos impacto en otros procesos?

Me quedan dos soluciones candidatas, fuera de R:

Solución 1 es utilizar una ruta de la biblioteca temporal y elimine la antigua biblioteca antigua y mover el nuevo en su lugar. El inconveniente de esto es que elimina + movimientos puede incurrir en algún tiempo durante el cual nada está disponible.

La solución 2 consiste en utilizar enlaces simbólicos para apuntar a una biblioteca (o jerarquía de bibliotecas) y simplemente sobrescribir un enlace simbólico con un puntero a una nueva biblioteca donde reside el paquete actualizado. Parece que eso implica menos tiempo de inactividad del paquete, el tiempo que le lleva al SO sobrescribir un enlace simbólico. La desventaja de esto es que requiere mucho más cuidado en la administración de enlaces simbólicos, y es específico de la plataforma.

Sospecho que la solución # 1 podría ser modificado para ser como # 2, mediante un uso inteligente de .libPaths(), pero esto parece que uno tiene que no llamada update.packages() y en lugar de escribir un nuevo actualizador que encuentra los paquetes obsoletos, instalaciones a una biblioteca temporal, y luego actualiza las rutas de la biblioteca. La ventaja de esto es que se podría limitar un proceso existente para la .libPaths() que tenía cuando comenzó (es decir, el cambio de las rutas de biblioteca R conoce acerca de que podría no ser propagada a aquellos casos que ya están ejecutando, sin alguna intervención explícita dentro de esa instancia).


Actualización 1. En el caso de ejemplo, las dos instancias R competidoras están en la misma máquina. Esto no es un requisito: por lo que entiendo las actualizaciones, si las dos comparten las mismas bibliotecas, es decir, los mismos directorios en una unidad compartida, entonces la actualización aún puede causar problemas, incluso si la otra instancia de R está en otra máquina . Entonces, uno podría matar accidentalmente un proceso R y ni siquiera verlo.

Respuesta

3

Mi fuerte suposición es que no hay forma de evitar esto.

Especialmente cuando un paquete incluye código compilado, no puede quitar y reemplazar la DLL mientras está en uso y esperar que funcione. Todos los punteros en la DLL utilizada por las llamadas R a esas funciones solicitarán una ubicación de memoria particular y la encontrarán inexplicablemente desaparecida. (Nota - mientras yo utilizo el término "DLL" aquí, quiero decir que, en un sentido no específico para Windows, ya que se utiliza, por ejemplo, en el archivo de ayuda para ?getLoadedDLLs "Biblioteca compartida" es quizás el término más genérico. .)

(Algunos de confirmación de mis sospechas proviene de the R for Windows FAQ, que informa de que 'Windows cerraduras DLL [a] paquete mientras se carga' que puede causar update.packages() a fallar.)

No estoy seguro exactamente cómo El mecanismo de carga lenta de R está implementado, pero imagine que también podría ser alterado por la eliminación de objetos que espera encontrar en direcciones particulares de la máquina.

Alguien más que sepa más sobre el funcionamiento interno de las computadoras seguramente dará una mejor respuesta que esta, pero esos son mis pensamientos.

+0

Se trata de una punto importante. Sospecho que el problema de una biblioteca compartida es un problema en todos los sistemas operativos. Para la mayoría del uso, me inclino a creer que esto mata la idea de hotswapping. El caso más estricto sería para los paquetes que no utilizan bibliotecas compartidas externas, pero no estoy seguro de cómo funciona para los paquetes que están completamente en R. – Iterator

+0

. Creo que su respuesta aplasta el sueño de hotswapping en general. Incluso si tengo un paquete R puro que me gustaría intercambiar, no es una buena práctica suponer que puedo hacer esto. Vincent tiene una respuesta razonable de cómo se puede hacer versiones, en lugar de intercambiar, lo cual tendré que adaptar bastante, pero está claro que esa es la única forma de evitar los conflictos que has señalado. – Iterator

4

En un entorno de producción, es probable que desee conservar al menos dos versiones, la actual y la anterior, para poder volver rápidamente a la anterior en caso de problema. Nada se sobrescribirá ni eliminará. Es más fácil hacer eso para todo el ecosistema R: tendría varios directorios, digamos "R-2.14.1-2011-12-22", "R-2.14.1-2012-01-27", etc., cada uno contiene todo (los ejecutables R y todos los paquetes). Esos directorios nunca se actualizarían: si se necesita una actualización, se crearía un nuevo directorio. (Algunos sistemas de archivos proporcionan "instantáneas" que le permiten tener muchos directorios muy similares sin uso indebido de espacio en disco).

El cambio de una versión a otra podría hacerse en el lado del usuario, cuando los usuarios inicien R, ya sea reemplazando el ejecutable R con un script que usaría la versión correcta, o configurando su variable de entorno PATH para que apunte a la versión deseada. Esto asegura que una sesión determinada siempre vea la misma versión de todo.

+0

Esta es una buena sugerencia, tanto para la capacidad de revertir/"retroceder" cambios y la capacidad de reproducir resultados. Necesito pensar un poco más sobre la sobrecarga de la información de la versión de comunicación. – Iterator

+0

Creo que has dado una excelente respuesta a las mejores prácticas. La respuesta de Josh está más centrada en por qué no hay un método seguro para hotswapping. Sobre la base de su respuesta, que he seleccionado, diría que su dirección de respuesta es lo que se debe hacer para abordar estos problemas. – Iterator

1

He aquí un escenario que me encontré ayer en Windows 7.

  1. estoy corriendo una sesión de R.
  2. Abra el PDF de un manual del paquete.
  3. Cierre todas las sesiones R. Olvídate de cerrar el manual del paquete PDF.
  4. abrir una nueva instancia de R, update.packages run()

La instalación falla, por supuesto, ya que Windows todavía tiene el PDF abierto y no puede sobrescribir ....

+0

+1 Eso sería bastante malo en un entorno compartido. No he probado en Linux con múltiples usuarios, pero me pregunto cómo funcionaría para una situación con, por ejemplo, 100 usuarios y alguien leyendo una viñeta de paquete ... – Iterator

+0

En Linux, eso no supondría ningún problema: de forma predeterminada, los archivos en uso no están bloqueados. Si el archivo PDF sigue ahí después de la actualización, , el visor de PDF notará el cambio, actualización y mostrará el nuevo. Si el archivo PDF ya no está allí, el visor de PDF probablemente continuará mostrando el anterior (el archivo no está realmente eliminado, está en un estado de limbo, todavía allí, sin nombre, y solo realmente desaparecer cuando todas las aplicaciones que lo leen cierran el archivo). En el peor de los casos, el visor de PDF mostraría un mensaje de error, pero no evitaría la actualización. –

Cuestiones relacionadas