JuliaLang / Distributed.jl

Create and control multiple Julia processes remotely for distributed computing. Ships as a Julia stdlib.
https://docs.julialang.org/en/v1/stdlib/Distributed/
MIT License
20 stars 8 forks source link

`isready(::AbstractWorkerPool)` is inconsistent with whether `take!` will block #87

Open kleinschmidt opened 1 year ago

kleinschmidt commented 1 year ago

isready(pool::AbstractWorkerPool) just checks whether there's something in pool.channel, but if that thing is PID that is not in procs(), then take!(pool) will throw it away, delete it from the pool, and block forever. The most straightforward way to address this would be to have isready do the same integrity check, or, to check at push!/put! (and hence also at construction time). The latter may be breaking, but IMO the inconsistency between take!, isready, and length is a bug that should be fixed.

MWE:

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.8.4 (2022-12-23)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> using Distributed

julia> pool = WorkerPool(collect(1:2))
WorkerPool(Channel{Int64}(9223372036854775807), Set([2, 1]), RemoteChannel{Channel{Any}}(1, 1, 1))

julia> isready(pool)
true

julia> fetch(pool.channel)
1

julia> take!(pool)
1

julia> isready(pool)
true

julia> fetch(pool.channel)
2

julia> procs()
1-element Vector{Int64}:
 1

julia> t = @async take!(pool)
Task (runnable) @0x00000001281ce570

julia> timedwait(() -> istaskdone(t), 1)
:timed_out