2011-05-31 17 views
7

Estoy escribiendo una función que necesita capturar un error que limita la velocidad al hacer ping a una API basada en web.Funciones que no se ejecutan antes de Sys.sleep()

estoy usando tryCatch a detectar el error, y dentro de esta función se especifica la siguiente función de error:

error=function(e) { 
       warning(paste(e,"\nWaiting an hour for rate limit to reset...")) 
       Sys.sleep(3600) # Wait an hour for rate-limit to reset 
       return(user.info(user, ego.count)) 
      } 

La función parece funcionar, pero cuando la comprobación de los registros de salida para el script noto que la mensaje de advertencia no se escribe hasta después de el tiempo de suspensión se ha agotado.

puedo reproducir este comportamiento en la consola R con:

print("Drew sucks") 
Sys.sleep(10) 

Diez segundos antes de Drew sucks se imprime en la consola. En mi función, me gustaría proporcionar algunos comentarios al usuario sobre esta larga pausa antes de que ocurra la pausa.

¿Qué está causando este comportamiento?

Respuesta

3

Por el placer de hacerlo, trate de:

system(sprintf('sleep %d', seconds)) 

Suponiendo que tenga el comando * NIX habitual del sueño en el camino.

+1

Una cosa: si se usa 'warning', el usuario puede usar' suprpressWarnings' para no mostrar mensajes. Con esta solución, se necesita otra forma. – Marek

2

probablemente relacionadas con el almacenamiento en búfer de salida - ver ?flush.console

+0

Por otro lado, la consola de E/S nunca se almacena en el búfer. Podría ser una excepción, pero sería una sorpresa, ¿no? Sin embargo, otra inspiración del esquema que querré ver (doh) ... – TheBlastOne

+2

Al agregar 'flush.console()' no se corrigió el problema en el ejemplo "Drew Sucks" de arriba. – DrewConway

3

Por defecto, las advertencias no se imprimen inmediatamente, sino que se imprimen después de los mejores rendimientos de funciones de nivel. Puede establecer warn a '1' si desea que se imprima inmediatamente, y aún más si lo quiere detener

+0

Hmm, después de volver a leer su publicación, no estoy seguro de estar respondiendo la pregunta correcta. Pensé que estabas diciendo que quieres que la advertencia() se imprima inmediatamente cuando se llame, ¿es así? – geoffjentry

+0

Sí, pero parece que el problema no se aplica solo a las llamadas 'warning', como en mi ejemplo' print'. – DrewConway

+0

Eso es lo que me hizo pensar que quizás no esté formulando tu pregunta. Si inicio R y ejecuto su ejemplo de impresión, obtengo el resultado de la impresión y luego el retraso. Si hacer lo mismo para usted realmente no realiza la impresión() antes del Sys.sleep(), algo más está sucediendo (por ejemplo, la respuesta de Hadley). Creo que te vas a encontrar con problemas con la advertencia() estando en una función de cualquier manera. – geoffjentry

7

Debe establecer immediate.=TRUE en su función de advertencia o establecer options(warn=1); y pueden agregar flush.console() (en algunos sistemas operativos) antes de la llamada Sys.sleep().

foo <- function() { 
    warning("uh-oh...", immediate.=TRUE) 
    flush.console() 
    Sys.sleep(5) 
    "done" 
} 
foo() 
# Warning in foo() : uh-oh... 
# [1] "done" 

Los detalles se explican en la sección "Detalles" de ?warning. Parafraseando, "if options (warn = 0), las advertencias se almacenan e imprimen después de que se haya completado la función de nivel superior, si las opciones (warn = 1) se imprimen a medida que ocurren".

+0

Puede ser un problema de sistema operativo, pero en OS X esa función todavía ejecuta la llamada 'Sys.sleep' antes de imprimir la advertencia. – DrewConway

+0

Funciona para mí en Windows y Ubuntu (y Ubuntu no necesita 'flush.console()'). –

+0

@DrewConway Funciona para mí en OSX corriendo a través del terminal. ¿Estás en la GUI? (o más específicamente, cuál, si es así) –

Cuestiones relacionadas