> > And just of curiosity, when current task calls `read()` and there's no > data available, does Julia switch to another task or lets operating system > to switch thread?
Switches to another task. The reading task on the Julia side calls libuv to initiate reading, then waits on a condition variable. The actual blocking call is made in libuv. Once data is available, there is a callback from libuv to Julia and the read task is woken up. On Tue, May 17, 2016 at 4:36 PM, Andrei Zh <[email protected]> wrote: > Hmm, I now think that I could misinterpret exception (EOFError, if I > remember correctly) - it could be a server who closed connection by > timeout, not Julia's `read()`. I will check it once again and post back if > I see any suspicious behavior. Thanks for clarification. > > And just of curiosity, when current task calls `read()` and there's no > data available, does Julia switch to another task or lets operating system > to switch thread? > > On Tuesday, May 17, 2016 at 6:14:39 PM UTC+3, Jameson wrote: >> >> > But if nothing is written to the socket for a while, `read()` will fail >> with timeout >> >> That sounds like a bug, although I'm not aware of any read code-path that >> has a timeout. Can you post an example of when it fails? This should >> absolutely be the correct way to handle IO. >> >> >> >> On Tue, May 17, 2016 at 3:09 AM Andrei Zh <[email protected]> wrote: >> >>> Jameson, thanks for your reply. Basically, the question is what exactly >>> to do in a task that handles a socket. E.g. I can't do just: >>> >>> @async begin >>> socket = connect(...) >>> while true >>> data = read(socket, Int64) >>> process_data(data) >>> end >>> end >>> this only works if there's something to read all the time. But if >>> nothing is written to the socket for a while, `read()` will fail with >>> timeout. >>> >>> This is why I'm looking for a way to make a call to `read()` only when >>> there's actually something to read. So far I came to the following function >>> that does exactly this, but may have (configurable) delay: >>> >>> """ >>> Parameters: >>> * sockets - list of sockets to select from >>> * readfn - function that takes socket and returns read result >>> * sleep_time - (optional) - interval between socket checks >>> * channel_size - (optional) size of a result channel, effectively, >>> buffer size >>> Returns: >>> * channel with objects that were read from sockets >>> """ >>> function select(sockets::Vector{TCPSocket}, readfn::Function; >>> sleep_time::Float64=0.1, channel_size::Int64=1024) >>> result_channel = Channel(channel_size) >>> for s in sockets >>> @async begin >>> Base.start_reading(s) >>> while isopen(s) >>> while nb_available(s) == 0 sleep(sleep_time) end >>> result = readfn(s) >>> put!(result_channel, result) >>> end >>> end >>> end >>> return result_channel >>> end >>> >>> Better implementation that would remove possible delay is welcome. >>> >>> >>> On Tuesday, May 17, 2016 at 8:18:16 AM UTC+3, Jameson wrote: >>>> >>>> Launch each socket into it's own task (@async) and let Julia's >>>> green-threading manage the poll/select for you internally. >>>> >>>> >>>> On Friday, May 13, 2016 at 8:08:01 PM UTC-4, Andrei Zh wrote: >>>>> >>>>> 1. I found out that TCPSocket contains several conditions and >>>>> callbacks, but I couldn't find any docs or example of their usage. >>>>> 2. I also found #6563 <https://github.com/JuliaLang/julia/issues/6563> >>>>> that >>>>> discusses exactly the problem of listening to multiple conditions / >>>>> channels. >>>>> >>>>> So if I manage to create a callback for incoming data, I will be able >>>>> to borrow some ideas from (1) and come up with a `select` function that >>>>> satisfies my needs. Does anybody have an example of using TCPSocket's >>>>> callbacks/conditions? >>>>> >>>>> On Thursday, May 12, 2016 at 12:45:44 AM UTC+3, Andrei Zh wrote: >>>>>> >>>>>> Given several TCPSocket-s, how can I sequentially poll them and read >>>>>> the first that becomes readable? >>>>>> >>>>>> I believe *nix's poll/select functions provide something similar for >>>>>> files (and Julia has `poll_fd`), but what is the best way to approach >>>>>> this >>>>>> task for sockets? >>>>>> >>>>>
