2011-09-03 18 views
8

Mientras trabajo en una consola R, me gustaría configurar una tarea en segundo plano que supervisa una conexión en particular y cuando se produce un evento, se ejecuta otra función (una alerta). Alternativamente, puedo configurar cosas para que una función externa simplemente envíe una alerta a R, pero este parece ser el mismo problema: es necesario configurar un oyente.¿Puede la consola R soportar tareas en segundo plano o interrupciones (gestión de eventos)?

Puedo hacer esto en un proceso dedicado de R, pero no sé si esto es factible desde una consola. Además, no estoy interesado en interrumpir R si está calculando una función, pero alertando o interrumpiendo si la consola simplemente está esperando la entrada.

Aquí hay tres casos de uso:

  1. El ejemplo más simple posible está viendo un archivo. Supongamos que tengo un archivo llamado "latestData.csv" y quiero monitorear los cambios; cuando cambia, se ejecuta myAlert(). (Se puede ampliar para hacer cosas diferentes, pero solo aparece una nota que dice que un archivo ha cambiado.)

  2. Un tipo diferente de monitor observaría si una máquina determinada tiene poca memoria RAM y podría ejecute un save.image() y termine. Nuevamente, esto podría ser un simple problema de ver un archivo producido por un monitor externo que guarda la salida de top o algún otro comando.

  3. Un ejemplo diferente es como otra pregunta reciente sobre SO: have R halt the EC2 machine it's running on. Si una alerta de otra máquina o proceso le dice al programa que guarde & finalice, entonces poder escuchar esa alerta sería genial.

Por el momento, sospecho que hay dos maneras de manejar esta vía: Rserve y, posiblemente, a través de fork. Si alguien tiene ejemplos de cómo hacer esto con un paquete o mediante otro método, sería genial. Creo que resolver cualquiera de estos tres casos de uso los resolvería a todos, modulo un poco de código externo.


Nota 1: Me di cuenta, per this answer to another SO question que R es un solo subproceso, por lo que sospecho fork y Rserve puede funcionar. Sin embargo, no estoy seguro acerca de la viabilidad si uno está interactuando con una terminal R. Aunque R's REPL se adjunta a la entrada de la consola, estoy tratando de evitar esto o imitarlo, que es donde fork o Rserve pueden ser la respuesta.

Nota 2: Para aquellos que estén familiarizados con los métodos de manejo de eventos/eventos, eso resolvería todo, también. Yo no he encontrado nada sobre esto en R.


Actualización 1: Me he dado cuenta que el manual para escribir extensiones R has a section referencing event handling, que menciona el uso de R_PolledEvents. Esto parece prometedor.

Respuesta

3

Depende si quiere interrumpir el ralentí o el trabajo R. Si es el primero, puede pensar en eludir el R REPL predeterminado por algún detector de eventos que pondrá en cola los eventos entrantes y los evaluará. La opción común es usar tcl/tk o gtk loop; He hecho algo como esto en torno a libev en mi paquete triggr, que hace que las solicitudes de resumen R provengan de un socket.

El último caso es casi imposible, a menos que realice manualmente el código computacional para ejecutar el código if(evenOccured) processIt periódicamente.

El multihebra no es una opción real, porque como sabrá, dos intérpretes en un proceso se romperán utilizando las mismas variables globales, mientras que los procesos bifurcados tendrán contenidos de memoria independientes.

+0

¿Puedes aclarar tu segundo párrafo? Estoy feliz de que algo revise un estado periódicamente. +1 para las sugerencias sobre tcl/tk y gtk. Definitivamente miraré 'triggr' y veré si puedo adaptarlo o las ideas. – Iterator

+0

Miré 'triggr', pero supongo que tendré que mirar los métodos tcl/tk o gtk, como sugieres. – Iterator

0

algunas ideas:

  1. Run R desde dentro el guión de otro idioma (esto es posible, por ejemplo, en Perl usando RSPerl) y utilizan el guión envoltorio para poner en marcha el oyente.

  2. Otra opción puede ser ejecutar un comando externo (que no sea R) (usando system()) desde dentro de R que lanzará un oyente en segundo plano.

  3. Ejecutando R en modo de proceso por lotes en el fondo antes de ejecutando R o en una ventana separada.

    Por ejemplo:

    R --no-guardar < listener.R> output.out &

    El oyente puede enviar un correo electrónico approraite cuando se produce el evento.

1

Resulta que el paquete Rdsm es compatible con esto también.

Con este paquete, se puede configurar una relación servidor/cliente entre diferentes instancias de R, cada uno es un terminal R básico, y el servidor puede enviar mensajes, incluidas funciones, a los clientes.

Transformado en el caso de uso que describí, el proceso del servidor puede hacer cualquier monitoreo que sea necesario, y luego enviar mensajes a los clientes. La documentación es un poco escueta, desafortunadamente, pero la funcionalidad parece ser directa.

Si el proceso del servidor es, por ejemplo, monitorear una conexión (un archivo, un conducto, una URL, etc.) regularmente y se encuentra un desencadenador, puede enviar un mensaje a los clientes.

Aunque el propósito principal del paquete es la memoria compartida (que es la que encontré), este mensaje también funciona bastante bien para otros fines.


Actualización 1: Por supuesto, para el paso de mensajes, no se puede ignorar MPI y el paquete Rmpi. Eso puede ser el truco, pero el paquete Rdsm se inicia/funciona con las consolas R, que es el tipo de interfaz que había buscado. Todavía no estoy seguro de qué es lo que admite Rmpi.

9

Una opción más es el svSocket package. No es bloqueante

Aquí está un 8 minute video usándolo, que tiene más de 3.000 visitas. Muestra cómo convertir una sesión R en un servidor y cómo enviar comandos a ella y recibir datos de vuelta. Demuestra hacer eso incluso cuando el servidor está ocupado; p.ej.por ejemplo, si inicia un proceso prolongado y olvida guardar los resultados intermedios, puede conectarse al servidor y obtener los resultados (antes de que hayan terminado).

+0

+1 ¡Gracias! Parece que es justo lo que estoy buscando. Me pregunto si lo he usado antes, ya que su comportamiento parece algo que tenía en mente. Le daré un giro y veré si funciona. – Iterator

Cuestiones relacionadas