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

**URL:** https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001
**Category:** Performance
**Created:** [April 4, 2022, 11:13am UTC](https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001 "2022-04-04T11:13:45Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)
#### Post date: [April 4, 2022, 11:13am UTC](https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001/1 "2022-04-04T11:13:45Z")

</div>

I have `@spawnat expression` run inside a function in a module and get the following error:

```julia
module Test
using Distributed

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

end

julia> Test.test()
ERROR: On worker 2:
UndefVarError: Test not defined

```

It looks like somehow the remote process needs to know about `Test` but I don’t understand why. `t` is just a local variable and it must have no binding to the name `Test`.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [April 4, 2022, 12:33pm UTC](https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001/2 "2022-04-04T12:33:39Z")

</div>

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:

```julia
[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 `gensym`d, but then how would that be communicated to the remote process?

---

<div class="post-metadata">

### Author: ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)
#### Post date: [April 4, 2022, 1:54pm UTC](https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001/3 "2022-04-04T13:54:07Z")

</div>

How could there be more than one module referencing that variable `t`? `t` is only visible inside `Test.test()` and the module `Test` lives only in the calling process.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [April 4, 2022, 2:53pm UTC](https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001/4 "2022-04-04T14:53:09Z")

</div>

It’s not about `t`. `@spawnat` doesn’t even know about it - it’s a seperate, special variable that’s the problem here whose exclusive purpose is facilitating communication between processes. It’s the

> [@Sukera](#):
>
> `Main.Test.:(var"##sync#48")`

that’s the problem, not `t`. This variable is required to make sure that the remote process knows where to send the result to.

---

<div class="post-metadata">

### Author: ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)
#### Post date: [April 5, 2022, 12:10am UTC](https://discourse.julialang.org/t/spawn-at-fails-when-called-inside-a-function-in-a-module/79001/5 "2022-04-05T00:10:39Z")

</div>

Thank you for the useful comment! Come to think of it, it seems inevitable for the remote process to know the namespace of where the remote call is made, in order to push a result back to the calling process. And the expanded macro looks in line with the speculation. So, the correct way to call `test()` would be (indeed it succeeds):

```julia
@everywhere module Test ... end

Test.test()

```
