Skip to content

Commit 0467de6

Browse files
committed
Add an extension to support Revise
1 parent be12fd4 commit 0467de6

4 files changed

Lines changed: 113 additions & 3 deletions

File tree

Project.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
77
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
88
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
99

10+
[weakdeps]
11+
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
12+
13+
[extensions]
14+
ReviseExt = "Revise"
15+
1016
[compat]
1117
Aqua = "0.8"
1218
Distributed = "1"
1319
LibSSH = "0.7"
1420
LinearAlgebra = "1"
1521
Random = "1"
22+
Revise = "3.7.0"
1623
Serialization = "1"
1724
Sockets = "1"
1825
Test = "1"
19-
julia = "1.9"
26+
julia = "1.10"
2027

2128
[extras]
2229
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
@@ -26,4 +33,4 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
2633
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2734

2835
[targets]
29-
test = ["Aqua", "Distributed", "LibSSH", "LinearAlgebra", "Test"]
36+
test = ["Aqua", "Distributed", "LibSSH", "LinearAlgebra", "Revise", "Test"]

docs/src/_changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ This documents notable changes in DistributedNext.jl. The format is based on
1111

1212
### Added
1313
- Implemented callback support for workers being added/removed etc ([#17]).
14+
- Added a package extension to support Revise.jl ([#17]).
1415

1516
### Fixed
1617
- Modified the default implementations of methods like `take!` and `wait` on

ext/ReviseExt.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module ReviseExt
2+
3+
import DistributedNext
4+
import DistributedNext: myid, workers, remotecall
5+
6+
import Revise
7+
8+
9+
struct DistributedNextWorker <: Revise.AbstractWorker
10+
id::Int
11+
end
12+
13+
function get_workers()
14+
map(DistributedNextWorker, workers())
15+
end
16+
17+
function Revise.remotecall_impl(f, worker::DistributedNextWorker, args...; kwargs...)
18+
remotecall(f, worker.id, args...; kwargs...)
19+
end
20+
21+
Revise.is_master_worker(::typeof(get_workers)) = myid() == 1
22+
Revise.is_master_worker(worker::DistributedNextWorker) = worker.id == 1
23+
24+
function __init__()
25+
Revise.register_workers_function(get_workers)
26+
DistributedNext.add_worker_started_callback(pid -> Revise.init_worker(DistributedNextWorker(pid));
27+
key="DistributedNext-integration")
28+
end
29+
30+
end

test/distributed_exec.jl

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

3+
import Revise
34
using DistributedNext, Random, Serialization, Sockets
45
import DistributedNext
56
import DistributedNext: launch, manage
@@ -1957,7 +1958,9 @@ include("splitrange.jl")
19571958

19581959
@testset "Clear all workers for timeout tests (issue #45785)" begin
19591960
nprocs() > 1 && rmprocs(workers())
1960-
begin
1961+
1962+
# This test requires kill(), and that doesn't work on Windows before 1.11
1963+
if !(Sys.iswindows() && VERSION < v"1.11")
19611964
# First, assert that we get no messages when we close a cooperative worker
19621965
w = only(addprocs(1))
19631966
@test_nowarn begin
@@ -1975,6 +1978,8 @@ include("splitrange.jl")
19751978
end
19761979
wait(rmprocs([w]))
19771980
end
1981+
else
1982+
@warn "Skipping timeout tests because kill() isn't supported on Windows for this Julia version"
19781983
end
19791984
end
19801985

@@ -2048,6 +2053,73 @@ end
20482053
DistributedNext.remove_worker_exited_callback(exited_key)
20492054
end
20502055

2056+
# This is a simplified copy of a test from Revise.jl's tests
2057+
@testset "Revise.jl integration" begin
2058+
function rm_precompile(pkgname::AbstractString)
2059+
filepath = Base.cache_file_entry(Base.PkgId(pkgname))
2060+
isa(filepath, Tuple) && (filepath = filepath[1]*filepath[2]) # Julia 1.3+
2061+
for depot in DEPOT_PATH
2062+
fullpath = joinpath(depot, filepath)
2063+
isfile(fullpath) && rm(fullpath)
2064+
end
2065+
end
2066+
2067+
pid = only(addprocs(1))
2068+
2069+
# Test that initialization succeeds by checking that Main.whichtt is defined
2070+
# on the worker, which is defined by Revise.init_worker().
2071+
@test timedwait(() ->remotecall_fetch(() -> hasproperty(Main, :whichtt), pid), 10) == :ok
2072+
2073+
tmpdir = mktempdir()
2074+
@everywhere push!(LOAD_PATH, $tmpdir) # Don't want to share this LOAD_PATH
2075+
2076+
# Create a fake package
2077+
module_file = joinpath(tmpdir, "ReviseDistributed", "src", "ReviseDistributed.jl")
2078+
mkpath(dirname(module_file))
2079+
write(module_file,
2080+
"""
2081+
module ReviseDistributed
2082+
2083+
f() = π
2084+
g(::Int) = 0
2085+
2086+
end
2087+
""")
2088+
2089+
# Check that we can use it
2090+
@everywhere using ReviseDistributed
2091+
for p in procs()
2092+
@test remotecall_fetch(ReviseDistributed.f, p) == π
2093+
@test remotecall_fetch(ReviseDistributed.g, p, 1) == 0
2094+
end
2095+
2096+
# Test changing and deleting methods
2097+
write(module_file,
2098+
"""
2099+
module ReviseDistributed
2100+
2101+
f() = 3.0
2102+
2103+
end
2104+
""")
2105+
for p in procs()
2106+
# We call Revise.revise() inside the timedwait() because file events
2107+
# on macOS can have significant latency, meaning a single revise() call
2108+
# may not pick up the changes yet.
2109+
@test timedwait(10; pollint=0.5) do
2110+
Revise.revise()
2111+
remotecall_fetch(ReviseDistributed.f, p) == 3.0
2112+
end == :ok
2113+
2114+
@test_throws RemoteException remotecall_fetch(ReviseDistributed.g, p, 1)
2115+
end
2116+
2117+
rmprocs(workers())
2118+
rm_precompile("ReviseDistributed")
2119+
pop!(LOAD_PATH)
2120+
end
2121+
2122+
20512123
# Run topology tests last after removing all workers, since a given
20522124
# cluster at any time only supports a single topology.
20532125
if nprocs() > 1

0 commit comments

Comments
 (0)