JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.72k stars 5.48k forks source link

Tcpsocket and @async problem #10589

Closed freddycct closed 9 years ago

freddycct commented 9 years ago
function f()
    task1 = @async begin
        server = listen(2000)
        socket = accept(server)
    end

    socket = wait(task1)
    println(typeof(socket))
end

f()

Error: socket is undefined

I get the error that socket is undefined. This works in REPL but not when the program is executed from inside a function f()

Note: Julia v 0.36

pao commented 9 years ago

This is #10405, which is fixed on master. I am not sure if it's suitable for backport since someone might be relying on that behavior. @tkelman?

freddycct commented 9 years ago

So only available on v0.4 but not v0.3+ ?

pao commented 9 years ago

Not currently, no.

tkelman commented 9 years ago

There have been a bunch of intermittent TypeErrors and other CI instabilities that seem to be related (or uncovered?) by that one so I would vote against backporting that change.

freddycct commented 9 years ago

So how do I get access to variables computed inside an @async begin ... end ?

Keno commented 9 years ago

@pao Can you explain how this is #10405? I also see the same behavior on master.

Keno commented 9 years ago

Anyway, the problem here is the extra socket in the @async block (please note to put quotes around macro name to avoid notifying github users). Without it works fine:

julia> function f()
           task1 = @async begin
               server = listen(2000)
               accept(server)
           end

           socket = wait(task1)
           println(typeof(socket))
       end
f (generic function with 1 method)

julia> f()
TCPSocket
freddycct commented 9 years ago

So is there any bug? Please reopen if this is not the same as #10405. I don't see why I can't use socket = accept(server), I thought everything inside @async is localized. infact the following fails too with the return statement...

function f()
    task1 = @async begin
        server = listen(2000)
        socket = accept(server)
        return socket
    end

    socket = wait(task1)
    println(typeof(socket))
end

f()
Keno commented 9 years ago

Well, it's hard to say. It's basically working as expected within the semantics of the language, because inner function capture locals:

julia> function f()
       g() = x
       x = 1
       g
       end
f (generic function with 1 method)

julia> f()()
1

with the inherent consequence that if you use the local (in the task) before it's assigned you get an error. So everything is working as intended, though it may be surprising.

Keno commented 9 years ago

I guess the macro could recognize variables that are only assigned, but not read before? @JeffBezanson does that seem reasonable?

pao commented 9 years ago

Can you explain how this is #10405?

From the description in the original issue, it was an error from an async task which wasn't being reported, which is exactly #10405. But it appears you have this under control.

freddycct commented 9 years ago

It works when I use different variable names and not use the same variable name in @async

function f()
    task1 = @async begin
        server = listen(2000)
        socket = accept(server)
    end

    socket_1 = wait(task1)
    println(typeof(socket_1))
end

f()
JeffBezanson commented 9 years ago

dup of #2669