@spawn at fails when called inside a function in a module

It’s because the remote process has to know where to put the result. There’s a module wide sync variable for distributed operations, according to the source of @spawnat and what the macro expands to:

[sukera@tempman ~]$ julia -q -p 2
julia> using Distributed

julia> module Test
       using Distributed

       function test()
           t = @spawnat :2 1==1
           @show fetch(t)
       end

       end
Main.Test

julia> using .Test

julia> @code_lowered Test.test()
CodeInfo(
1 ─       Core.NewvarNode(:(value))
│         Core.NewvarNode(:(t))
│         #1 = %new(Main.Test.:(var"#1#2"))
│   %4  = #1
│         ref = Distributed.spawnat($(QuoteNode(2)), %4)
└──       goto #3 if not false
2 ─       Distributed.put!(Main.Test.:(var"##sync#48"), ref)
3 ┄       t = ref
│   %9  = Main.Test.fetch(t)
│         value = %9
│   %11 = Base.repr(%9)
│         Base.println("fetch(t) = ", %11)
└──       return value
)

Distributed creates a Future, passes that to the external process to place the result into and then assigns that Future to t. I’m not sure if that requires knowing the Test module though, may be a bug.

EDIT: thinking about this some more, it does require knowing about the containing module, because there may be more than one module referencing that variable. I guess it could be gensymd, but then how would that be communicated to the remote process?

1 Like