@@ -163,9 +163,11 @@ impl WorkerPool {
163
163
}
164
164
} ;
165
165
166
- let precompiled_policies =
166
+ // Use a reference counter to share access to precompiled policies
167
+ // between workers. This reduces memory usage
168
+ let precompiled_policies: Arc < PrecompiledPolicies > =
167
169
match precompile_policies ( & engine, & bootstrap_data. fetched_policies ) {
168
- Ok ( pp) => pp ,
170
+ Ok ( pp) => Arc :: new ( pp ) ,
169
171
Err ( e) => {
170
172
eprintln ! ( "{e}" ) ;
171
173
std:: process:: exit ( 1 ) ;
@@ -202,10 +204,16 @@ impl WorkerPool {
202
204
warn ! ( "policy timeout protection is disabled" ) ;
203
205
}
204
206
207
+ // Use a reference counter to share access to policies
208
+ // between workers. This reduces memory usage
209
+ let policies = Arc :: new ( bootstrap_data. policies ) ;
210
+
205
211
for n in 1 ..=pool_size {
206
212
let ( tx, rx) = mpsc:: channel :: < EvalRequest > ( 32 ) ;
207
213
worker_tx_chans. push ( tx) ;
208
214
215
+ // Each worker has its own wasmtime::Engine, sharing the
216
+ // same engine across all the workers leads to bad performance
209
217
let engine = match wasmtime:: Engine :: new ( & wasmtime_config) {
210
218
Ok ( e) => e,
211
219
Err ( e) => {
@@ -225,16 +233,17 @@ impl WorkerPool {
225
233
} ;
226
234
worker_engines. push ( engine. clone ( ) ) ;
227
235
228
- let policies = bootstrap_data. policies . clone ( ) ;
229
236
let modules = precompiled_policies. clone ( ) ;
230
237
let b = barrier. clone ( ) ;
231
238
let canary = boot_canary. clone ( ) ;
232
239
let callback_handler_tx = self . callback_handler_tx . clone ( ) ;
233
240
let always_accept_admission_reviews_on_namespace =
234
241
self . always_accept_admission_reviews_on_namespace . clone ( ) ;
242
+ let policies = policies. clone ( ) ;
235
243
236
244
let join = thread:: spawn ( move || -> Result < ( ) > {
237
245
info ! ( spawned = n, total = pool_size, "spawning worker" ) ;
246
+
238
247
let mut worker = match Worker :: new (
239
248
rx,
240
249
& policies,
@@ -252,6 +261,10 @@ impl WorkerPool {
252
261
return Err ( anyhow ! ( "Worker {} couldn't start: {}" , n, e) ) ;
253
262
}
254
263
} ;
264
+ // Drop the Arc references ASAP, they are no longer needed
265
+ // at this point
266
+ drop ( policies) ;
267
+ drop ( modules) ;
255
268
b. wait ( ) ;
256
269
257
270
debug ! ( id = n, "worker loop start" ) ;
@@ -262,6 +275,13 @@ impl WorkerPool {
262
275
} ) ;
263
276
join_handles. push ( join) ;
264
277
}
278
+
279
+ // Deallocate all the memory used by the precompiled policies since
280
+ // they are no longer needed. Without this explicit cleanup
281
+ // the reference would be dropped right before Policy Server exits,
282
+ // meaning a lot of memory would have been consumed without a valid reason
283
+ // during the whole execution time
284
+ drop ( precompiled_policies) ;
265
285
barrier. wait ( ) ;
266
286
267
287
if !boot_canary. load ( Ordering :: SeqCst ) {
0 commit comments