1+ export Context, addprocs!, rmprocs!
2+
13"""
24 Context(xs::Vector{OSProc}) -> Context
35 Context(xs::Vector{Int}) -> Context
@@ -15,21 +17,18 @@ Special fields include:
1517mutable struct Context
1618 procs:: Vector{Processor}
1719 proc_lock:: ReentrantLock
18- proc_notify:: Threads.Condition
1920 log_sink:: Any
2021 profile:: Bool
2122 options
2223end
2324
2425function Context (procs:: Vector{P} = Processor[OSProc (w) for w in procs ()];
25- proc_lock= ReentrantLock (), proc_notify= Threads. Condition (),
26- log_sink= TimespanLogging. NoOpLog (), log_file= nothing , profile= false ,
27- options= nothing ) where {P<: Processor }
26+ proc_lock= ReentrantLock (), log_sink= TimespanLogging. NoOpLog (),
27+ log_file= nothing , profile= false , options= nothing ) where {P<: Processor }
2828 if log_file != = nothing
2929 @warn " `log_file` is no longer supported\n Please instead load `GraphViz.jl` and use `render_logs(logs, :graphviz)`."
3030 end
31- Context (procs, proc_lock, proc_notify, log_sink,
32- profile, options)
31+ Context (procs, proc_lock, log_sink, profile, options)
3332end
3433Context (xs:: Vector{Int} ; kwargs... ) = Context (map (OSProc, xs); kwargs... )
3534Context (ctx:: Context , xs:: Vector = copy (procs (ctx))) = # make a copy
@@ -62,41 +61,90 @@ procs(ctx::Context) = lock(ctx) do
6261end
6362
6463"""
65- addprocs!(ctx::Context, xs)
64+ addprocs!(xs) -> Processor[]
6665
67- Add new workers `xs` to `ctx`.
66+ Add new workers `xs` to the eager scheduler and returns the ones that were
67+ actually added.
6868
6969Workers will typically be assigned new tasks in the next scheduling iteration
7070if scheduling is ongoing.
7171
7272Workers can be either `Processor`s or the underlying process IDs as `Integer`s.
7373"""
74- addprocs! (ctx:: Context , xs:: AbstractVector{<:Integer} ) = addprocs! (ctx, map (OSProc, xs))
75- function addprocs! (ctx:: Context , xs:: AbstractVector{<:OSProc} )
76- lock (ctx) do
77- append! (ctx. procs, xs)
74+ addprocs! (xs:: AbstractVector{<:Integer} ) = addprocs! (map (OSProc, xs))
75+ function addprocs! (xs:: AbstractVector{<:Processor} )
76+ Sch. init_eager ()
77+
78+ ctx = Sch. eager_context ()
79+ state = Sch. EAGER_STATE[]
80+
81+ to_add = setdiff (xs, procs (ctx))
82+
83+ timespan_start (ctx, :addprocs! , nothing , nothing )
84+
85+ # Initialize new procs
86+ for p in to_add
87+ Sch. init_proc (state, p, ctx. log_sink)
88+
89+ # Empty the processor cache list and force reschedule
90+ lock (state. lock) do
91+ state. procs_cache_list[] = nothing
92+ end
93+ put! (state. chan, Sch. RescheduleSignal ())
7894 end
79- lock (ctx. proc_notify) do
80- notify (ctx. proc_notify)
95+
96+ lock (ctx) do
97+ append! (ctx. procs, to_add)
8198 end
99+ timespan_finish (ctx, :addprocs! , nothing , nothing )
100+
101+ return to_add
82102end
83103
84104"""
85- rmprocs!(ctx::Context, xs)
105+ rmprocs!(xs) -> Processor[]
86106
87- Remove the specified workers `xs` from `ctx`.
107+ Remove the specified workers `xs` from the eager scheduler and returns the ones
108+ that were actuall added.
88109
89110Workers will typically finish all their assigned tasks if scheduling is ongoing
90111but will not be assigned new tasks after removal.
91112
92113Workers can be either `Processor`s or the underlying process IDs as `Integer`s.
93114"""
94- rmprocs! (ctx:: Context , xs:: AbstractVector{<:Integer} ) = rmprocs! (ctx, map (OSProc, xs))
95- function rmprocs! (ctx:: Context , xs:: AbstractVector{<:OSProc} )
96- lock (ctx) do
97- filter! (p -> (p ∉ xs), ctx. procs)
115+ rmprocs! (xs:: AbstractVector{<:Integer} ) = rmprocs! (map (OSProc, xs))
116+ function rmprocs! (xs:: AbstractVector{<:Processor} )
117+ Sch. init_eager ()
118+
119+ ctx = Sch. eager_context ()
120+ state = Sch. EAGER_STATE[]
121+
122+ _rmprocs! (ctx, state, xs; allow_empty= false )
123+ end
124+
125+ function _rmprocs! (ctx:: Context , state, xs; allow_empty= true )
126+
127+ if ! allow_empty && Set (procs (ctx)) == Set (xs)
128+ throw (ArgumentError (" Refusing to remove all processors from the Dagger.Context, at least one must be present." ))
129+ end
130+
131+ to_remove = intersect (xs, procs (ctx))
132+
133+ timespan_start (ctx, :rmprocs! , nothing , nothing )
134+
135+ for p in to_remove
136+ Sch. cleanup_proc (state, p, ctx. log_sink)
137+
138+ # Empty the processor cache list
139+ lock (state. lock) do
140+ state. procs_cache_list[] = nothing
141+ end
98142 end
99- lock (ctx. proc_notify) do
100- notify (ctx. proc_notify)
143+
144+ lock (ctx) do
145+ filter! (p -> (p ∉ to_remove), ctx. procs)
101146 end
147+ timespan_finish (ctx, :rmprocs! , nothing , nothing )
148+
149+ return to_remove
102150end
0 commit comments