# Readavailable with timeout

**URL:** https://discourse.julialang.org/t/readavailable-with-timeout/39585
**Category:** Web Stack
**Created:** [May 16, 2020, 2:57pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585 "2020-05-16T14:57:49Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [May 16, 2020, 2:57pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/1 "2020-05-16T14:57:49Z")

</div>

I would like to read the first message out of a websocket as soon as it arrives, but also I want to close the connection if nothing arrives within a second.

How can I do that?

Example:

```julia
task = @async HTTP.WebSockets.listen("127.0.0.1", UInt16(9091)) do ws
    while !eof(ws)
        cmd = JSON.parse(String(readavailable(ws)))
        println(cmd)
     end
end

```

The `readavailable` function does not have a timeout parameter. If I call it then it may block indefinitely. The `eof` function does not block at all, so it cannot be used to “wait for the first message”.

So how do I do this?

Background info: I want to create a server that can respond **quickly** , closes the connection if there is no communication for a while.

---

<div class="post-metadata">

### Author: ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)
#### Post date: [May 16, 2020, 4:43pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/2 "2020-05-16T16:43:13Z")

</div>

I had a similar problem, except that I needed to read at most one message. I solved it with the following function, which may point you towards a solution for your case. The idea is to create a timer that interrupts the asynchronous task:

```julia
function async_reader(io::IO, timeout_sec)::Channel
    ch = Channel(1)
    task = @async begin
        reader_task = current_task()
        function timeout_cb(timer)
            put!(ch, :timeout)
            Base.throwto(reader_task, InterruptException())
        end
        timeout = Timer(timeout_cb, timeout_sec)
        data = String(readavailable(io))
        timeout_sec > 0 && close(timeout) # Cancel the timeout
        put!(ch, data)
    end
    bind(ch, task)
    return ch
end

```

I call it like this:

```
ch_out = async_reader(io, timeout)
out = take!(ch_out) # if out===:timeout, a timeout occurred

```

So, `out` is equal to either the data from `io`, or `:timeout`. The `take!` function will block for at most `timeout` seconds.

---

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [May 16, 2020, 6:33pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/3 "2020-05-16T18:33:45Z")

</div>

Thank you for your answer. It does work, but it creates a Channel, a Timer and a Task for each read operation. It seems to be an overkill.

Probably I could rewrite async\_reader to put data into the channel in a loop. But then I would have to use the same timeout for all operations, and it would still create and cancel a Timer object for each read operation, even if there is plenty of data available.

It cannot be efficient. I cannot write speedy network I/O with this. There must be a better way.

---

<div class="post-metadata">

### Author: ![GregMcC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregmcc/32/14827_2.png) [@GregMcC](https://discourse.julialang.org/u/GregMcC)
#### Post date: [August 3, 2020, 12:09pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/4 "2020-08-03T12:09:02Z")

</div>

I would have expected the result from the **readAvailable** function would be binary : Yes or No ( true or false ) without any waiting, as per other languages. Then the readAvailable can be used in a loop - and divert the routine to take action ( such as reading the input **read(stdin, Char)** when it is known that there is a character to be read. ) Seems very strange to me that _ **readAvailable** _ should hang the process to wait for an input - surely that is not what was intended - at the moment it operating no different than the standard **read** function

---

<div class="post-metadata">

### Author: ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)
#### Post date: [August 4, 2020, 5:07pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/5 "2020-08-04T17:07:38Z")

</div>

`readavailable` blocking is actually the intended behavior. You can do what you describe by using [`bytesavailable`](https://docs.julialang.org/en/v1.6-dev/base/io-network/#Base.bytesavailable).

---

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [August 5, 2020, 5:27am UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/6 "2020-08-05T05:27:32Z")

</div>

Actually, you can’t do that with `bytesavailable`, because it is also a synchronous function. What I really wanted (e.g. wait at most 2 seconds for data to be available) cannot be done with synchronous/blocking functions.

---

<div class="post-metadata">

### Author: ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)
#### Post date: [August 5, 2020, 1:08pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/7 "2020-08-05T13:08:34Z")

</div>

I am not sure what you mean by synchronous. What I meant is that `bytesavailable` is not blocking; that is, if there is nothing to read, it immediately returns `0`, which I think is what @GregMcC wanted.

---

<div class="post-metadata">

### Author: ![Laszlo\_Nagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laszlo_nagy/32/14565_2.png) [@Laszlo\_Nagy](https://discourse.julialang.org/u/Laszlo_Nagy)
#### Post date: [August 6, 2020, 6:21am UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/8 "2020-08-06T06:21:35Z")

</div>

Originally, this is my question and I wanted to the server to respond quickly, and close the connection if there is no communication **for a while** (e.g. a few seconds).

@GremMcC did not have a question, he was just suprised.

Back to the original question: `bytesavailable` does not block, that is true. But `bytesavailable` cannot be used to “wait for incoming data and act quickly”. Simply because it does not wait at all. It cannot respond to external events efficiently. On the other side, `readavailable` could be used to respond to incoming data quickly (because it blocks until data is available, but then returns immediately), but it may block the program indefinitely, and does not fulfill the second condition (be able to close the connection if there is no communication for a while).

We only have two functions. One may block forever, the other does not block at all. There is nothing in between. The perfect solution would be to add a timeout parameter to `readavailable`. The workaround provided by @mbaz works, but it is clumsy, and probably not nearly as efficient as it should be. Integrating `readavailable` with the core I/O loop would be the best solution. Starting a new thread for reading data, and interrupting with an external exception is clearly not a good way to do it. But this is the only way, as far as I can see.

---

<div class="post-metadata">

### Author: ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)
#### Post date: [August 6, 2020, 1:39pm UTC](https://discourse.julialang.org/t/readavailable-with-timeout/39585/9 "2020-08-06T13:39:36Z")

</div>

I hear you: for me, the hardest part of coding Gaston (a plotting package based on gnuplot) has always been reading/writing to/from streams. I’m still not sure my solution is optimal.

Having said that, what I’ve heard from the developers these past few years is, the way to do streaming I/O is to wrap the I/O functions in a task and use channels. My understanding is that this is the Julian way to do it. Since Julia is optimized for this use case, it should be faster and more efficient than it looks at first sight.

Of course, the state of I/O can still be significantly improved, both in documentation and implementation. I think this is one of the main issues to follow or contribute to: [Review of IO blocking behaviour · Issue #24526 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/24526).
