Skip to content

Commit 449077e

Browse files
committed
Add an extension to support Revise
1 parent d5d1c90 commit 449077e

File tree

4 files changed

+103
-1
lines changed

4 files changed

+103
-1
lines changed

Project.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ 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
Distributed = "1"
1218
Random = "1"
19+
Revise = "3.6.5"
1320
Serialization = "1"
1421
Sockets = "1"
1522
julia = "1.9"
@@ -21,4 +28,4 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
2128
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2229

2330
[targets]
24-
test = ["LinearAlgebra", "Test", "LibSSH", "Distributed"]
31+
test = ["LinearAlgebra", "Test", "LibSSH", "Distributed", "Revise"]

docs/src/_changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This documents notable changes in DistributedNext.jl. The format is based on
1717
and DistributedNext may be active and adding workers. This should help prevent
1818
incompatibilities from both libraries being used simultaneously ([#10]).
1919
- Implemented callback support for workers being added/removed etc ([#17]).
20+
- Added a package extension to support Revise.jl ([#17]).
2021

2122
## [v1.0.0] - 2024-12-02
2223

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
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_added_callback(pid -> Revise.init_worker(DistributedNextWorker(pid));
27+
key="DistributedNext-integration")
28+
end
29+
30+
end

test/distributed_exec.jl

Lines changed: 64 additions & 0 deletions
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
@@ -1969,6 +1970,69 @@ end
19691970
@test length(exited_workers) == 1
19701971
end
19711972

1973+
# This is a simplified copy of a test from Revise.jl's tests
1974+
@testset "Revise.jl integration" begin
1975+
function rm_precompile(pkgname::AbstractString)
1976+
filepath = Base.cache_file_entry(Base.PkgId(pkgname))
1977+
isa(filepath, Tuple) && (filepath = filepath[1]*filepath[2]) # Julia 1.3+
1978+
for depot in DEPOT_PATH
1979+
fullpath = joinpath(depot, filepath)
1980+
isfile(fullpath) && rm(fullpath)
1981+
end
1982+
end
1983+
1984+
pid = only(addprocs(1))
1985+
1986+
# Test that initialization succeeds by checking that Main.whichtt is defined
1987+
# on the worker, which is defined by Revise.init_worker().
1988+
@test timedwait(() ->remotecall_fetch(() -> hasproperty(Main, :whichtt), pid), 10) == :ok
1989+
1990+
tmpdir = mktempdir()
1991+
@everywhere push!(LOAD_PATH, $tmpdir) # Don't want to share this LOAD_PATH
1992+
1993+
# Create a fake package
1994+
module_file = joinpath(tmpdir, "ReviseDistributed", "src", "ReviseDistributed.jl")
1995+
mkpath(dirname(module_file))
1996+
write(module_file,
1997+
"""
1998+
module ReviseDistributed
1999+
2000+
f() = π
2001+
g(::Int) = 0
2002+
2003+
end
2004+
""")
2005+
2006+
# Check that we can use it
2007+
@everywhere using ReviseDistributed
2008+
for p in procs()
2009+
@test remotecall_fetch(ReviseDistributed.f, p) == π
2010+
@test remotecall_fetch(ReviseDistributed.g, p, 1) == 0
2011+
end
2012+
2013+
# Test changing and deleting methods
2014+
write(module_file,
2015+
"""
2016+
module ReviseDistributed
2017+
2018+
f() = 3.0
2019+
2020+
end
2021+
""")
2022+
Revise.revise()
2023+
for p in procs()
2024+
# We use timedwait() here because worker updates from Revise are asynchronous
2025+
@test timedwait(() -> remotecall_fetch(ReviseDistributed.f, p) == 3.0, 10) == :ok
2026+
2027+
@test_throws RemoteException remotecall_fetch(ReviseDistributed.g, p, 1)
2028+
end
2029+
2030+
rmprocs(workers())
2031+
rm_precompile("ReviseDistributed")
2032+
pop!(LOAD_PATH)
2033+
end
2034+
2035+
19722036
# Run topology tests last after removing all workers, since a given
19732037
# cluster at any time only supports a single topology.
19742038
if nprocs() > 1

0 commit comments

Comments
 (0)