# Client/Server TCP Hidden Error - is Julia reliable?

**URL:** https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353
**Category:** General Usage
**Tags:** error
**Created:** [October 1, 2019, 8:59am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353 "2019-10-01T08:59:17Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 8:59am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/1 "2019-10-01T08:59:17Z")

</div>

I have a server and a client, both written in Julia. I’m using the Sockets module from the standard Julia library.

I have an issue on the client where I connect to a server and read from a server. I read from the socket in a separate process via a remotecall. In the main thread I then send data to the server.

I experience a soft lock after writing. It appears as though the culprit is calling eof() in the remote call (which blocks) but the result is odd. There doesn’t seem to be an exception or error. It also doesn’t seem to be blocked by any IO as it appears to send() successfully. It just seems to halt directly after I read (and then print some debug info)

For the sake of this error I have simplified the implementation to demonstrate what’s happening

This is the serverside. I basically send data every 0.5 seconds

```julia
import Sockets
import Future
import Distributed

function main()

    server = Sockets.listen(50009)
    sock = Sockets.accept(server)
    dt = 0.5
    startTime = time();

    while (true)

          
        elapsed = time() - startTime

        if elapsed > dt
            write(sock, 1)

            startTime = time()
        end

    end

end

main()

```

Then client side, where I read and send data every 0.5 seconds. I read via a remotecall

```julia
import Sockets
import Future
import Distributed

function ReadAsync(sock::Sockets.TCPSocket)

    try
        println(" ASYNC Begin.")
        timestamp = 0.0
        funcVal = 0.0

        arr = Float64[]
        while !eof(sock)
        # push!(arr, read(sock, Float64))
        end

        println(" ASYNC END.")
        return timestamp, funcVal
    catch e
        println("caught it $e")
    end
    
end

function main()

    clientTime = 0.0
    lastHeardTimeout = 10.0
    dt = 0.5
    timestamp = 0.0
    funcVal = 0.0

    sock = Sockets.connect("localhost", 50009);
    println("Ready and waiting...")

    # Start a thread that checks for reads.
    r = remotecall(ReadAsync, 1, sock)

    startTime = time();
    lastHeardTime = time();
    try
    
        number = 0.0
    
        while true
    
            elapsed = time() - startTime

            if elapsed > dt
            
                clientTime = clientTime + dt

                elapsedHeardTime = time() - lastHeardTime
        
                if (elapsedHeardTime < lastHeardTimeout && iswritable(sock))
                    println("Socket Writable.")
                    numBytes = write(sock, clientTime)
                    println("Socket Wrritten.")
                    println(" IT HALTS HERE !!!!")
                    println("Continues")
                else 
                    println("I haven't heard from the server in awhile...")
                end
    
                startTime = time() # the sync waits for the previous async to be finished before starting the next iteration   
            end
        end
    
    catch e
        println("caught it $e")
        close(sock)
    end

    close(sock)
end

main()

```

I’m obviously doing something wrong here. But my lack of experience and lack of immediate error is making me a bit stuck.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 9:05am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/2 "2019-10-01T09:05:24Z")

</div>

> [@Wednesday](#):
>
> ```julia
> while !eof(sock)
> # push!(arr, read(sock, Float64))
> end
> 
> ```

Why did you comment out the `read` call?

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 9:26am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/3 "2019-10-01T09:26:33Z")

</div>

I did this just to demonstrate the issue. With the comment, I would expect this to not yield a result, however I would not expect it to cause a halt in the main process (in an unexpected way), which is currently what happens and I’m not sure as to why

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [October 1, 2019, 9:35am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/4 "2019-10-01T09:35:13Z")

</div>

First idea: I think you’re missing a yield in:  
`while !eof(sock)`

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 9:35am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/5 "2019-10-01T09:35:23Z")

</div>

Isn’t the case that you have an infinite loop with no yield points (`eof` returns `false` immidiately).

Insert a `yield()` in there should fix it.

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 9:38am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/6 "2019-10-01T09:38:30Z")

</div>

Would not having yield cause unexpected results? I get that the remote call will never yield a value in this circumstance, but why does that affect the main process.

The halt occurs after, the write(). It HALTS HERE is never reached. Is this expected to happen with a lack of yield in a remote call?

```julia
           numBytes = write(sock, clientTime)
                    println("Socket Wrritten.")
                    println(" IT HALTS HERE !!!!")

```

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [October 1, 2019, 9:39am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/7 "2019-10-01T09:39:44Z")

</div>

Because you schedule the remotecall on the main process…  
You’d need to do `addprocs(1)` and then schedule on 2

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 9:41am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/8 "2019-10-01T09:41:12Z")

</div>

The comment

```julia
# Start a thread that checks for reads.

```

Seems to be a part of the misunderstanding. You are not spawning a new thread, you simply start a task (co-routine) on the main thread. If that task is spinning in a loop, nothing else in the thread can progress.

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 9:43am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/9 "2019-10-01T09:43:31Z")

</div>

Ah okay, I think I misunderstood remote calls. How would I go about implementing this then? Since eof() will block right?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 9:45am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/10 "2019-10-01T09:45:07Z")

</div>

`eof` can block but if it blocks it will yield to the scheduler so another task can progress.

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 9:48am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/11 "2019-10-01T09:48:37Z")

</div>

So the scheduler “skips” over IO functionality that blocks?  
Edit: Also shouldn’t eof() yield?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 9:53am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/12 "2019-10-01T09:53:00Z")

</div>

> [@Wednesday](#):
>
> So the scheduler “skips” over IO functionality that blocks?

Not sure what you mean. IO that blocks will yield to the scheduler so that if there are other tasks in flight, they can take over and do progress.

> [@Wednesday](#):
>
> Also shouldn’t eof() yield?

In the case that there is data available in the stream it immediately returns `false`. I don’t know if it would be better to unconditionally yield in `eof`.

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 9:54am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/13 "2019-10-01T09:54:57Z")

</div>

> In the case that there is data available in the stream it immediately returns `false` . I don’t know if it would be better to unconditionally yield in `eof` .

In this case, there is data in the stream, thus it should return false, which means this coroutine is yielding right?

edit: ah wait sorry it’s in a while.

extra edit: So how would I actually check data is available to be read in socket?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 10:39am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/14 "2019-10-01T10:39:45Z")

</div>

There is `bytesavailable`. But why do you need that?

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 11:00am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/15 "2019-10-01T11:00:19Z")

</div>

Because according to the documentation eof() will block to wait for more data. So I need to check if the stream is empty before checking it’s the end of the file, otherwise in the event my server has sent me nothing, i’ll be stuck in my coroutine again, blocked by eof()

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 11:06am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/16 "2019-10-01T11:06:06Z")

</div>

> [@Wednesday](#):
>
> otherwise in the event my server has sent me nothing, i’ll be stuck in my coroutine again, blocked by eof()

You will not be stuck because it will yield to another task which can progress. Sure, the particular task will be blocked, waiting for data but that doesn’t mean your other tasks are stuck. That’s kind of the point of asynchronous code, different parts of the code can be blocked on different things while other tasks are working. When the tasks get something to read, the scheduler will resume the task and it will continue.

---

<div class="post-metadata">

### Author: ![Wednesday](https://avatars.discourse-cdn.com/v4/letter/w/91b2a8/32.png) [@Wednesday](https://discourse.julialang.org/u/Wednesday)
#### Post date: [October 1, 2019, 11:17am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/17 "2019-10-01T11:17:14Z")

</div>

It’s only asynchronous in that the scheduler keeps track of the point of execution. Tasks are still only processed one after the other (atleast on the same thread). The former creates an level of complexity which can be quite troublesome. Because then I need to ensure tasks become synchronized (in order to maintain the order of my data that I receive and sen). I’m sure there is the API to do this, but I can achieve the same outcome, serially, if I had the ability to have non-blocked IO.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 1, 2019, 11:22am UTC](https://discourse.julialang.org/t/client-server-tcp-hidden-error-is-julia-reliable/29353/18 "2019-10-01T11:22:47Z")

</div>

> [@Wednesday](#):
>
> It’s only asynchronous in that the scheduler keeps track of the point of execution. Tasks are still only processed one after the other (atleast on the same thread).

That is what asynchronous (or concurrent execution) means (see e.g [multithreading - How to articulate the difference between asynchronous and parallel programming? - Stack Overflow](https://stackoverflow.com/a/17766943/10447964)). Perhaps you want to run things in parallel. Then, you need to (as already been said) start workers with `addprocs` and start tasks on the new workers with `remotecall(f, pid)` with `pid` not being 1.
