93 lines
2.5 KiB
Julia
93 lines
2.5 KiB
Julia
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
|
|
|
import Base: launch, manage, connect, exit
|
|
|
|
mutable struct UnixDomainCM <: ClusterManager
|
|
np::Integer
|
|
end
|
|
|
|
function launch(manager::UnixDomainCM, params::Dict, launched::Array, c::Condition)
|
|
# println("launch $(manager.np)")
|
|
cookie = Base.cluster_cookie()
|
|
for i in 1:manager.np
|
|
sockname = tempname()
|
|
try
|
|
cmd = `$(params[:exename]) --startup-file=no $(@__FILE__) udwrkr $sockname $cookie`
|
|
io, pobj = open(cmd, "r")
|
|
|
|
wconfig = WorkerConfig()
|
|
wconfig.userdata = Dict(:sockname=>sockname, :io=>io, :process=>pobj)
|
|
push!(launched, wconfig)
|
|
notify(c)
|
|
catch e
|
|
println(e)
|
|
end
|
|
end
|
|
end
|
|
|
|
function connect(manager::UnixDomainCM, pid::Int, config::WorkerConfig)
|
|
if myid() == 1
|
|
# println("connect_m2w")
|
|
config.connect_at = get(config.userdata)[:sockname] # This will be useful in the worker-to-worker connection setup.
|
|
|
|
print_worker_stdout(get(config.userdata)[:io], pid)
|
|
else
|
|
# println("connect_w2w")
|
|
sockname = get(config.connect_at)
|
|
config.userdata = Dict{Symbol, Any}(:sockname=>sockname)
|
|
end
|
|
|
|
t = time()
|
|
while true
|
|
try
|
|
address = get(config.userdata)[:sockname]
|
|
if isa(address, Tuple)
|
|
sock = connect(address...)
|
|
else
|
|
sock = connect(address)
|
|
end
|
|
return (sock, sock)
|
|
catch e
|
|
if (time() - t) > 30.0
|
|
rethrow(e)
|
|
else
|
|
sleep(0.1)
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
# WORKER
|
|
function start_worker(sockname, cookie)
|
|
Base.init_worker(cookie, UnixDomainCM(0))
|
|
|
|
srvr = listen(sockname)
|
|
while true
|
|
sock = accept(srvr)
|
|
Base.process_messages(sock, sock)
|
|
end
|
|
end
|
|
|
|
function manage(manager::UnixDomainCM, id::Int, config::WorkerConfig, op)
|
|
# Does not seem to be required, filesystem entry cleanup is happening automatically on process exit
|
|
# if op == :deregister
|
|
# try
|
|
# rm(get(config.userdata)[:sockname])
|
|
# end
|
|
# end
|
|
nothing
|
|
end
|
|
|
|
function print_worker_stdout(io, pid)
|
|
@schedule while !eof(io)
|
|
line = readline(io)
|
|
println("\tFrom worker $(pid):\t$line")
|
|
end
|
|
end
|
|
|
|
if (length(ARGS) > 0) && (ARGS[1] == "udwrkr")
|
|
# script has been launched as a worker
|
|
start_worker(ARGS[2], ARGS[3])
|
|
end
|