From 0789d7796505019accea50696e7afe67df7b2a86 Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Sun, 4 Aug 2024 01:02:34 +0200 Subject: [PATCH] Implement Base.isempty(::RemoteChannel) The default method from Base has the nasty side-effect of take!()'ing from the underlying channel. --- docs/src/_changelog.md | 4 ++++ src/remotecall.jl | 3 +++ test/distributed_exec.jl | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/docs/src/_changelog.md b/docs/src/_changelog.md index 014863b..fe80fb4 100644 --- a/docs/src/_changelog.md +++ b/docs/src/_changelog.md @@ -9,6 +9,10 @@ This documents notable changes in DistributedNext.jl. The format is based on ## Unreleased +### Fixed +- Fixed behaviour of `isempty(::RemoteChannel)`, which previously had the + side-effect of taking an element from the channel ([#3]). + ### Changed - Added a `project` argument to [`addprocs(::AbstractVector)`](@ref) to specify the project of a remote worker ([#2]). diff --git a/src/remotecall.jl b/src/remotecall.jl index 0b1143d..644ff04 100644 --- a/src/remotecall.jl +++ b/src/remotecall.jl @@ -768,6 +768,9 @@ close(rr::RemoteChannel) = call_on_owner(close_ref, rr) isopen_ref(rid) = isopen(lookup_ref(rid).c) isopen(rr::RemoteChannel) = call_on_owner(isopen_ref, rr) +isempty_ref(rid) = isempty(lookup_ref(rid).c) +Base.isempty(rr::RemoteChannel) = call_on_owner(isempty_ref, rr) + getindex(r::RemoteChannel) = fetch(r) getindex(r::Future) = fetch(r) diff --git a/test/distributed_exec.jl b/test/distributed_exec.jl index a5aea3e..a5b833b 100644 --- a/test/distributed_exec.jl +++ b/test/distributed_exec.jl @@ -493,6 +493,18 @@ let ch = RemoteChannel(() -> Channel(1)) @test 10 == test_iteration_collect(ch) end +# Test isempty(::RemoteChannel). This should not modify the underlying +# AbstractChannel, which Base's default implementation will do. +let + chan = Channel(1) + push!(chan, 1) + remotechan = RemoteChannel(() -> chan) + + @test !isempty(remotechan) + # Calling `isempty(remotechan)` shouldn't have modified `chan` + @test !isempty(chan) +end + # make sure exceptions propagate when waiting on Tasks @test_throws CompositeException (@sync (@async error("oops"))) try