-
-
Notifications
You must be signed in to change notification settings - Fork 414
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
stdout doesn't flush correctly #238
Comments
What operating system do you have? This may be a libc problem. |
I am using Mac OS X 10.10, julia 0.3.1. |
interesting enough, if i set |
I think that this is an IPython issue. The basic problem here is that stdio output is sent to IPython via Turning on verbose mode probably slows things down just enough that the stream message arrives before IPython moves on to the next code cell. cc: @minrk |
There shouldn't be any race condition on the frontend. The kernel decides where output goes by setting the parent_header of output messages. Are there race conditions or async events happening in the kernel itself? Can the idle message that indicates a cell is complete be sent before an output message? |
so, is it possible to attach |
Sorry for the multiple references...I kept doing stupid things...you should check this one https://github.com/randy3k/IJulia.jl/commit/9104817dde3f7cb24e66d10d3ee15c8c74dd351f |
It seems that the fix only relief the problem but not solve the problem. If |
Check https://github.com/JuliaLang/IJulia.jl/pull/239/files I believe I solved it. |
This is tough, since Julia uses async io everywhere (like JavaScript/nodejs) unlike more traditional languages, which sometimes are more synchronous. flush is an extremely weak guarantee ("make sure my libc file buffers are emptied"), but for something small and local also happens to be enough, since the kernel likes to transfer small amounts of data eagerly. Readavailable is the equivalent of flush on the receive side ("give me everything that was in my libc buffer already"). Both of these fail to acknowledge that io needs actual external structure (such as a \0 inserted into the stream), not timing-based assumptions. |
…r const flag, make some changes for #238 (not fixed yet)
(Note that, if I recall correctly, IPython does not even attempt to capture stdout from external C code, only Python stdout, so we are being a bit more ambitious here and life is a bit harder here because we are dependent on libc.) |
What does IPython do with data printed from a thread? That is quite similar to life in Julia |
Routing is handled entirely by the msg_id in the parent_header. Each msg_id is associated with an output area. Since IPython stores the parent in a single location that is looked up when output messages are constructed, background thread IO will be associated with the most recently executed cell. |
IJulia also stores the parent in a single location (the global The issue here is just to make sure that buffers are flushed at the end of an execute request, so that we capture all available I/O to send at that time. If the I/O system decides not to make the bytes available to read until later (e.g. because of some hidden buffering?) then the output will get attached to a later execution cell... IJulia has no way of knowing where stdio should go except via the time that the bytes are available. |
it seems that flush_cstdio() is not synchronized, we have to add a little delay. https://github.com/randy3k/IJulia.jl/commit/a7a2d96b98fcc38c325f3820f3041640e528b19c edit: also, we have to flush again after pyout for something like the first cell. |
Adding some arbitrary delay seems quite fragile to me. I would rather call some (platform-specific?) "really flush this stream" library routine, but that might not always be possible. (e.g. consider the case of an external library that uses a custom buffering I/O library ... for example, some Fortran implementations might do this). |
i agree, it is just to demonstrate what was causing the problem. |
thing gets more complicated if we want to align the "foo" and "a" in the above example, since ipython doesn't know the order of execution.. |
Julia doesn't know the order of execution either: it doesn't know when or where anything in the stdout buffer came from, especially output originating in external libraries. The basic issue is that there are multiple I/O buffers involved here, some of which are not under Julia's control. |
Instead of sleeping during the read loop to throttle the number of stream messages sent, we now continually read the read_stdout and read_stderr streams (whose buffers are limited to 64KB on OSX/Linux, 4KB Windows?) and add data read into our own IOBuffers for STDOUT/STDERR. The rate of sending is now controlled by a stream_interval parameter; a stream message is now sent at most once every stream_interval seconds (currently 0.1). The exception to this is if the buffer has reached the size specified in max_size (currently 10KB), and will then be sent immediately. This is to avoid overly large stream messages being sent. Improves flush() so that it will have a very high chance of flushing data already written to stdout/stderr. The above changes fix JuliaLang#372 JuliaLang#342 JuliaLang#238 347 Adds timestamps to the debug logging and the task which the vprintln call is made from. Fixes using ?keyword (e.g. ?try)
Instead of sleeping during the read loop to throttle the number of stream messages sent, we now continually read the read_stdout and read_stderr streams (whose buffers are limited to 64KB on OSX/Linux, 4KB Windows?) and add data read into our own IOBuffers for STDOUT/STDERR. The rate of sending is now controlled by a stream_interval parameter; a stream message is now sent at most once every stream_interval seconds (currently 0.1). The exception to this is if the buffer has reached the size specified in max_size (currently 10KB), and will then be sent immediately. This is to avoid overly large stream messages being sent. Improves flush() so that it will have a very high chance of flushing data already written to stdout/stderr. The above changes fix JuliaLang#372 JuliaLang#342 JuliaLang#238 JuliaLang#347 Adds timestamps to the debug logging and the task which the vprintln call is made from. Fixes using ?keyword (e.g. ?try)
It happens when I select "run all". It works fine if I only run that cell. It may be also related to #172.
Edit:
It also seems that flushing doesn't help.
The text was updated successfully, but these errors were encountered: