Skip to content

Commit

Permalink
printtree -> dump
Browse files Browse the repository at this point in the history
  • Loading branch information
attdona committed Dec 6, 2023
1 parent 7b73582 commit 74f36aa
Showing 1 changed file with 58 additions and 48 deletions.
106 changes: 58 additions & 48 deletions src/Visor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -168,19 +168,20 @@ hold(::Supervisor) = nothing

Base.show(io::IO, process::Supervised) = print(io, "$(process.id)")

function printtree(node::Supervisor)
##function printtree(node::Supervisor)
function dump(node::Supervisor)
children = [
isa(p, Process) ? p.id : "supervisor:$(p.id)" for p in values(node.processes)
isa(p, Process) ? "$(p.id)($(p.status))" : "supervisor:$(p.id)($(p.status))" for p in values(node.processes)
]
println("[$node] nodes: $children")
for (id, el) in node.processes
if isa(el, Supervisor)
printtree(el)
dump(el)
end
end
end

printtree() = printtree(__ROOT__)
dump() = dump(__ROOT__)

function procs(node::Supervisor, tree::OrderedDict=OrderedDict())
children = OrderedDict()
Expand Down Expand Up @@ -210,11 +211,11 @@ function isprocstarted(name::String)
end

"""
supervisor(id, specs; intensity=1, period=5, strategy=:one_for_one, terminateif=:empty)::SupervisorSpec
supervisor(id, processes; intensity=1, period=5, strategy=:one_for_one, terminateif=:empty)::SupervisorSpec
Declare a supervisor of the nodes defined by the specification `specs`.
Declare a supervisor of one or more `processes`.
`specs` may be a single specification or a list of specifications.
`processes` may be a `Process` or an array of `Process`.
```jldoctest
julia> using Visor
Expand All @@ -239,7 +240,7 @@ See [Supervisor](@ref) documentation for more details.
"""
function supervisor(
id,
specs::Vector{<:Supervised}=Supervised[];
processes::Vector{<:Supervised}=Supervised[];
intensity=1,
period=5,
strategy=:one_for_one,
Expand All @@ -249,23 +250,23 @@ function supervisor(
error("wrong shutdown value $shutdown: must be one of :empty, :shutdown")
end

if isempty(specs) && terminateif === :empty
if isempty(processes) && terminateif === :empty
error("immediate shutdown of supervisor [$id] with no processes")
end

return Supervisor(id,
OrderedDict{String,Supervised}(map(spec -> spec.id => spec, specs)),
OrderedDict{String,Supervised}(map(spec -> spec.id => spec, processes)),
intensity, period, strategy, terminateif)
end

function supervisor(
id, spec::Supervised; intensity=1, period=5, strategy=:one_for_one, terminateif=:empty
id, proc::Supervised; intensity=1, period=5, strategy=:one_for_one, terminateif=:empty
)::Supervisor
if !(terminateif in [:shutdown, :empty])
error("wrong shutdown value $shutdown: must be one of :empty, :shutdown")
end

return Supervisor(id, OrderedDict(spec.id=>spec), intensity, period, strategy, terminateif)
return Supervisor(id, OrderedDict(proc.id=>proc), intensity, period, strategy, terminateif)
end

"""
Expand Down Expand Up @@ -466,16 +467,16 @@ end


"""
startup(spec::Spec)
startup(proc::Supervised)
Start the supervised nodes defined by `spec` as children of the root supervisor.
Start the supervised process defined by `proc` as children of the root supervisor.
"""
startup(spec::Supervised) = startup(__ROOT__, spec)
startup(proc::Supervised) = startup(__ROOT__, proc)

"""
startup(supervisor::Supervisor, spec::Spec)
startup(supervisor::Supervisor, proc::Supervised)
Start the supervised nodes defined by `spec` as children of `supervisor`.
Start the supervised process defined by `proc` as child of `supervisor`.
```jldoctest

Check failure on line 481 in src/Visor.jl

View workflow job for this annotation

GitHub Actions / Documentation

doctest failure in ~/work/Visor.jl/Visor.jl/src/Visor.jl:481-490 ```jldoctest julia> using Visor julia> foo(self) = println("foo process started"); julia> main(self) = startup(self.supervisor, process(foo)); julia> supervise([process(main)]); foo process started ``` Subexpression: supervise([process(main)]); Evaluated output: ERROR: supervise already active Stacktrace: [1] supervise(processes::Vector{Visor.Process}; intensity::Int64, period::Int64, strategy::Symbol, terminateif::Symbol, handler::Nothing, wait::Bool) @ Visor ~/work/Visor.jl/Visor.jl/src/Visor.jl:1156 [2] supervise(processes::Vector{Visor.Process}) @ Visor ~/work/Visor.jl/Visor.jl/src/Visor.jl:1137 [3] top-level scope @ none:1 Expected output: foo process started diff = Warning: Diff output requires color. foo process startedERROR: supervise already active Stacktrace: [1] supervise(processes::Vector{Visor.Process}; intensity::Int64, period::Int64, strategy::Symbol, terminateif::Symbol, handler::Nothing, wait::Bool) @ Visor ~/work/Visor.jl/Visor.jl/src/Visor.jl:1156 [2] supervise(processes::Vector{Visor.Process}) @ Visor ~/work/Visor.jl/Visor.jl/src/Visor.jl:1137 [3] top-level scope @ none:1
julia> using Visor
Expand All @@ -488,45 +489,54 @@ julia> supervise([process(main)]);
foo process started
```
"""
function startup(supervisor::Supervisor, spec::Supervised)
return call(supervisor, spec)
function startup(supervisor::Supervisor, proc::Supervised)
if !isdefined(supervisor, :task) || istaskdone(supervisor.task)
# start an empty supervisor
@async supervise(Supervised[])
yield()
end
if haskey(supervisor.processes, proc.id)
@warn "[$supervisor] already supervisioning proc [$proc]"
else
call(supervisor, proc)
end
end

function add_node(id::String, supervisor::Supervisor, spec::Supervised)
function add_node(id::String, supervisor::Supervisor, proc::Supervised)
try
@debug "[$supervisor] starting proc: [$spec]"
if isa(spec, Supervisor)
@debug "[$supervisor] starting proc: [$proc]"
if isa(proc, Supervisor)
# it is a supervisor
proc = start_processes(
supervisor,
id,
spec.processes;
intensity=spec.intensity,
period=spec.period,
strategy=spec.strategy,
terminateif=spec.terminateif,
proc.processes;
intensity=proc.intensity,
period=proc.period,
strategy=proc.strategy,
terminateif=proc.terminateif,
)
@async wait_child(supervisor, proc)
return proc
else
spec.supervisor = supervisor
supervisor.processes[spec.id] = spec
start(spec)
return spec
proc.supervisor = supervisor
supervisor.processes[proc.id] = proc
start(proc)
return proc
end
catch e
@error "[$supervisor] starting proc [$spec]: $e"
@error "[$supervisor] starting proc [$proc]: $e"
end
end

# add_node(supervisor::Supervisor, spec::Spec)
# add_node(supervisor::Supervisor, proc::Supervised)
#
# Add and start the process defined by specification `spec` to the `supervisor` list
# Add and start the process defined by `proc` to the `supervisor` list
# of managed processes.
#
# `add_node` is for internal use: it is not thread safe.
# For thread safety use the `startup` method.
add_node(supervisor::Supervisor, spec::Supervised) = add_node(spec.id, supervisor, spec)
add_node(supervisor::Supervisor, proc::Supervised) = add_node(proc.id, supervisor, proc)


# Start processes defined by `specs` specification.
Expand All @@ -535,24 +545,24 @@ add_node(supervisor::Supervisor, spec::Supervised) = add_node(spec.id, superviso
# `intensity` and `period` define process restart policy.
# `strategy` defines how to restart child processes.
function start_processes(
parent::Supervisor, name, specs; intensity, period, strategy, terminateif::Symbol=:empty
parent::Supervisor, name, procs; intensity, period, strategy, terminateif::Symbol=:empty
)::Supervisor
@debug "[$name]: start_processes with strategy $strategy"
svisor = Supervisor(parent, name, specs, intensity, period, strategy, terminateif)
svisor = Supervisor(parent, name, procs, intensity, period, strategy, terminateif)
svisor.inbox = Channel(INBOX_CAPACITY)
svisor.task = @async manage(svisor)
svisor.status = running

parent.processes[svisor.id] = svisor

for spec in values(specs)
for spec in values(procs)
add_node(svisor, spec)
end
return svisor
end

function start_processes(
svisor::Supervisor, childspecs; intensity, period, strategy, terminateif::Symbol=:empty
svisor::Supervisor, processes; intensity, period, strategy, terminateif::Symbol=:empty
)::Supervisor
@debug "[$svisor]: start_processes with strategy $strategy"
svisor.task = @async manage(svisor)
Expand All @@ -563,7 +573,7 @@ function start_processes(
svisor.strategy = strategy
svisor.terminateif = terminateif

for spec in childspecs
for spec in processes
add_node(svisor, spec)
end
return svisor
Expand Down Expand Up @@ -1089,15 +1099,15 @@ function wait_signal(sv)
end

"""
supervise(childspecs::Vector{<:Spec};
supervise(processes::Vector{<:Supervised};
intensity::Int=1,
period::Int=5,
strategy::Symbol=:one_for_one,
terminateif::Symbol=:empty,
handler::Union{Nothing, Function}=nothing,
wait::Bool=true)::Supervisor
The root supervisor start a family of supervised nodes defined by `specs`.
The root supervisor start a family of supervised `processes`.
Return the root supervisor or wait for supervisor termination if `wait` is true.
Expand Down Expand Up @@ -1125,7 +1135,7 @@ when process tasks throws exception and when a process terminate because of a `P
```
"""
function supervise(
specs::Vector{<:Supervised};
processes::Vector{<:Supervised};
intensity::Int=1,
period::Int=5,
strategy::Symbol=:one_for_one,
Expand All @@ -1149,7 +1159,7 @@ function supervise(
__ROOT__.evhandler = handler
sv = start_processes(
__ROOT__,
specs;
processes;
intensity=intensity,
period=period,
strategy=strategy,
Expand All @@ -1164,26 +1174,26 @@ function supervise(
end

"""
supervise(spec::Spec;
supervise(proc::Supervised;
intensity::Int=1,
period::Int=5,
strategy::Symbol=:one_for_one,
terminateif::Symbol=:empty,
handler::Union{Nothing, Function}=nothing,
wait::Bool=true)::Supervisor
The root supervisor start a supervised node defined by `spec`.
The root supervisor start a supervised process defined by `proc`.
"""
supervise(
spec::Supervised;
proc::Supervised;
intensity::Int=1,
period::Int=5,
strategy::Symbol=:one_for_one,
terminateif::Symbol=:empty,
handler::Union{Nothing,Function}=nothing,
wait::Bool=true,
)::Supervisor = supervise(
[spec];
[proc];
intensity=intensity,
period=period,
strategy=strategy,
Expand Down

0 comments on commit 74f36aa

Please sign in to comment.