Skip to content

Commit

Permalink
Merge pull request JuliaLang#31036 from tanmaykm/tan/fix31035
Browse files Browse the repository at this point in the history
start_worker option to close stdin redirect stdout
  • Loading branch information
tanmaykm committed Mar 19, 2019
2 parents ca36e57 + d2b00bd commit d76a30a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
17 changes: 9 additions & 8 deletions stdlib/Distributed/src/cluster.jl
Original file line number Diff line number Diff line change
Expand Up @@ -207,26 +207,27 @@ worker_timeout() = parse(Float64, get(ENV, "JULIA_WORKER_TIMEOUT", "60.0"))

## worker creation and setup ##
"""
start_worker([out::IO=stdout], cookie::AbstractString=readline(stdin))
start_worker([out::IO=stdout], cookie::AbstractString=readline(stdin); close_stdin::Bool=true, stderr_to_stdout::Bool=true)
`start_worker` is an internal function which is the default entry point for
worker processes connecting via TCP/IP. It sets up the process as a Julia cluster
worker.
host:port information is written to stream `out` (defaults to stdout).
The function closes stdin (after reading the cookie if required), redirects stderr to stdout,
listens on a free port (or if specified, the port in the `--bind-to` command
line option) and schedules tasks to process incoming TCP connections and requests.
The function reads the cookie from stdin if required, and listens on a free port
(or if specified, the port in the `--bind-to` command line option) and schedules
tasks to process incoming TCP connections and requests. It also (optionally)
closes stdin and redirects stderr to stdout.
It does not return.
"""
start_worker(cookie::AbstractString=readline(stdin)) = start_worker(stdout, cookie)
function start_worker(out::IO, cookie::AbstractString=readline(stdin))
start_worker(cookie::AbstractString=readline(stdin); kwargs...) = start_worker(stdout, cookie; kwargs...)
function start_worker(out::IO, cookie::AbstractString=readline(stdin); close_stdin::Bool=true, stderr_to_stdout::Bool=true)
init_multi()

close(stdin) # workers will not use it
redirect_stderr(stdout)
close_stdin && close(stdin) # workers will not use it
stderr_to_stdout && redirect_stderr(stdout)

init_worker(cookie)
interface = IPv4(LPROC.bind_addr)
Expand Down
36 changes: 36 additions & 0 deletions stdlib/Distributed/test/distributed_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,42 @@ cluster_cookie("foobar") # custom cookie
npids = addprocs_with_testenv(WorkerArgTester(`--worker=foobar`, false))
@test remotecall_fetch(myid, npids[1]) == npids[1]

# tests for start_worker options to retain stdio (issue #31035)
struct RetainStdioTester <: ClusterManager
close_stdin::Bool
stderr_to_stdout::Bool
end

function launch(manager::RetainStdioTester, params::Dict, launched::Array, c::Condition)
dir = params[:dir]
exename = params[:exename]
exeflags = params[:exeflags]

jlcmd = "using Distributed; start_worker(\"\"; close_stdin=$(manager.close_stdin), stderr_to_stdout=$(manager.stderr_to_stdout));"
cmd = detach(setenv(`$exename $exeflags --bind-to $(Distributed.LPROC.bind_addr) -e $jlcmd`, dir=dir))
proc = open(cmd, "r+")

wconfig = WorkerConfig()
wconfig.process = proc
wconfig.io = proc.out
push!(launched, wconfig)

notify(c)
end
manage(::RetainStdioTester, ::Integer, ::WorkerConfig, ::Symbol) = nothing


nprocs()>1 && rmprocs(workers())
cluster_cookie("")

for close_stdin in (true, false), stderr_to_stdout in (true, false)
npids = addprocs_with_testenv(RetainStdioTester(close_stdin,stderr_to_stdout))
@test remotecall_fetch(myid, npids[1]) == npids[1]
@test close_stdin != remotecall_fetch(()->isopen(stdin), npids[1])
@test stderr_to_stdout == remotecall_fetch(()->(stderr === stdout), npids[1])
rmprocs(npids)
end

# Issue # 22865
# Must be run on a new cluster, i.e., all workers must be in the same state.
rmprocs(workers())
Expand Down

0 comments on commit d76a30a

Please sign in to comment.