-
Notifications
You must be signed in to change notification settings - Fork 291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Display printed output while code is still running #3
Comments
We'll need to replace textConnection at some point. More when I'm back at the laptop. On Tue, Mar 25, 2014 at 6:49 PM, Thomas Kluyver notifications@github.com
|
I hoped that this would be fixed by the switch to for (x in 1:10) {
print(x)
Sys.sleep(1)
} |
here is info about the internals for reference: the code for connections is in /src/main/connections.c ( the function needs an /edit: the API is private, so this isn’t the way to go… |
we could maybe use |
See also discussion on #55. |
Not, that the python side also doesn't send any printed output during the evaluation until some |
In most cases, IPython can update output ~live. I think it flushes based on the time between successive writes to stdout. |
@takluyver I just had jupyter/jupyter_client#7, where without the flush nothing is displayed :-) |
I suspect there's a corner case where there's a short burst of things being written, followed by a long gap where nothing is printed. That's harder to resolve without using threads. |
In Julia, we run a green thread that blocks on the file descriptor of stdout, flushes the output to a stream message when something is available to read, and then sleeps for 100ms to allow output to accumulate before blocking again. Since this is a green thread, however, it can only wake up when something in Julia calls |
More examples in #230 -> it seems that this is only happening when you use a loop and the blocking process is in the loop. Also flushing the stdout doesn't matter: for (i in 1:5){
print("text")
flush.console()
flush(stdout())
Sys.sleep(1)
} Could it be that evaluate caches stdout? Update: for (i in 1:5){
print("text")
Sys.sleep(1)
}
print("break")
for (i in 1:5){
print("text")
Sys.sleep(1)
} -> it prints stdout in two bursts: the first 5 "text" lines + "break" and then the next 5 lines "text". This looks like evaluate only releases the text output once a "unit" of code (aka a line or multiple lines in case of a loop) is evaluated. |
Ok, looks like an evaluate issue: library(evaluate)
code <- "for (i in 1:5){
print(\"text\")
message('message')
Sys.sleep(1)
}
print(\"break\")
for (i in 1:5){
print(\"text\")
Sys.sleep(1)
}"
l = list()
txt <- function(o, type) {
t <- paste(o, collapse = '\n')
t <- paste("OUT: ", t)
l[length(l)+1] <<- paste("T: ",Sys.time()," type: ", type, " -> ", t)
}
oh <- new_output_handler(source = identity,
text = function(o) txt(o, "text"),
graphics = identity,
message = function(o) txt(o, "message"),
warning = function(o) txt(o, "warn"),
error = function(o) txt(o, "error"),
value = identity)
x <- evaluate(code, output_handler = oh)
l [[1]]
[1] "T: 2015-12-15 17:44:36 type: text -> OUT: [1] \"text\"\n"
[[2]]
[1] "T: 2015-12-15 17:44:36 type: message -> OUT: simpleMessage in message(\"message\"): message\n\n"
[[3]]
[1] "T: 2015-12-15 17:44:37 type: text -> OUT: [1] \"text\"\n"
[[4]]
[1] "T: 2015-12-15 17:44:37 type: message -> OUT: simpleMessage in message(\"message\"): message\n\n"
[[5]]
[1] "T: 2015-12-15 17:44:38 type: text -> OUT: [1] \"text\"\n"
[[6]]
[1] "T: 2015-12-15 17:44:38 type: message -> OUT: simpleMessage in message(\"message\"): message\n\n"
[[7]]
[1] "T: 2015-12-15 17:44:39 type: text -> OUT: [1] \"text\"\n"
[[8]]
[1] "T: 2015-12-15 17:44:39 type: message -> OUT: simpleMessage in message(\"message\"): message\n\n"
[[9]]
[1] "T: 2015-12-15 17:44:40 type: text -> OUT: [1] \"text\"\n"
[[10]]
[1] "T: 2015-12-15 17:44:40 type: message -> OUT: simpleMessage in message(\"message\"): message\n\n"
[[11]]
[1] "T: 2015-12-15 17:44:41 type: text -> OUT: [1] \"break\"\n"
[[12]]
[1] "T: 2015-12-15 17:44:46 type: text -> OUT: [1] \"text\"\n[1] \"text\"\n[1] \"text\"\n[1] \"text\"\n[1] \"text\"\n" -> the second 5 "text" things come in in one message |
And here is the problem: https://github.com/hadley/evaluate/blob/eb304135a5370a1ffad80717c50fe152ebeb7b4f/R/eval.r#L148
So unless there is any way to "observe" the content of a variable (threads? something in RStudio uses a |
great detective work! |
We have a plan to facilitate this at some point for all kernels by running them inside a wrapper process that captures stdout/stderr at the OS level. As and when we do that, we won't need to worry about capturing printed output in R; we can just write it to the process' real stdout, and it will get captured externally. |
Just tried if there is a way to observe the inputs to a connection: http://biostatmatt.com/R/R-conn-ints.pdf So making this work in the current system would require:
|
I'm not keen on the idea of maintaining anything written in C.
|
Hm, wild idea: if evaluate would overwrite |
I opened r-lib/evaluate#61 for the "overwrite flush.console idea". |
r-lib/evaluate#62 has the PR which implements flushing... After (and if...) that is released, we need to add |
Unfortunately no reply yet in r-lib/evaluate#62 :-( Has anybody here any connections to the devs? My last interaction with R devs left me a little scared, so I won't do a simple "ping" in the PR ... :-/ |
Hadley Wickham is really nice, but I haven't met the person who now maintains evaluate. I've risked a ping on the PR anyway ;-) |
i know noone there 😐 |
I don't know if its the same cause, but I'm getting a similar sort of bug with a loop that prints some text then draws a plot. Instead of getting the expected behaviour (text --> plot --> text --> plot --> etc.), it all gets jumbled up (text --> text --> plot --> text --> plot --> etc). Very similar effect in IPython was fixed with sys.stdout.flush() |
@alexvpickering Yep, this is the same cause... See also #295 for even more fun with this kind of things... |
As far as I remember, this could now be closed by adding this code before calling evaluate: r-lib/evaluate#62 (comment) evaluate::inject_funs(
flush.console = function() { base::flush.console(); evaluate::flush_console() },
flush = function(con) { base::flush(con); evaluate::flush_console() }
) |
oh nice! anyone want to do a PR or should we do it? |
fixed in c5daa14 |
The current implementation buffers printed output in a
textConnection()
until the user code has finished executing, then sends a singlestream
message with all the text. So you see no output until the cell finishes.If we can implement an object suitable to pass to sink, output can be displayed as it is printed.
The text was updated successfully, but these errors were encountered: