So I added the @sync
so I’d get the stdout on the shell. I think the real issue here is when the expression whatever(ref)
gets resolved. Let me point out the issue I have with the manual for the TCP server (the one using the nested @async
at the bottom of this section). I don’t believe it does what it claims to do by allowing multiple connections. Here:
server = listen(2000)
while true
sock = accept(server)
@async begin
x = readline(sock)
write(sock, x)
end
end
Then, in a shell just do > julia test.jl
. Pardon my python, but in IPython, I can then do:
In [1]: import socket
In [2]: s = socket.socket()
In [3]: s.connect(('', 2000))
In [4]: s.send('check check\n')
Out[4]: 12
In [5]: s.recv(1024)
Out[5]: 'check check'
Works great. However, there’s an issue with multiple connections.
In [1]: import socket
In [2]: s = socket.socket()
In [3]: t = socket.socket()
In [4]: s.connect(('', 2000))
In [5]: t.connect(('', 2000))
In [6]: s.send('check 1\n')
Out[6]: 8
In [7]: s.recv(1024)
And this hangs, waiting for the response. This is because the first @async
task is on the queue, blocking on reading from the s
socket. But after opening the t
socket, sock
gets redefined and instead the first task writes to the t
socket, which is not the appropriate client. Simple enough to confirm:
In [1]: import socket
In [2]: s = socket.socket()
In [3]: t = socket.socket()
In [4]: s.connect(('', 2000))
In [5]: t.connect(('', 2000))
In [6]: s.send('check 1\n')
Out[6]: 8
In [7]: t.recv(1024)
Out[7]: 'check 1'
These weren’t issues in 0.4.7 (I suspect they were introduced in 0.5 with some of the changes to function closures, but that’s speculation on my part). Perhaps this is expected, or even desired, behavior, but at the very least, the manual should be much clearer about the perils here.
Maybe I missed it in the language spec, but it would be nice to have tight control over when an expression is evaluated/resolved/etc.