Skip to content

Commit 4952405

Browse files
authored
refactor pod warmup to avoid vet warning (#3713)
By refactoring the parallel operation into a separate function, it should be easier to read and we avoid a loop-closure go-tcha.
1 parent 3d80f24 commit 4952405

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

porch/func/internal/podevaluator.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -205,29 +205,44 @@ func (pcm *podCacheManager) warmupCache(podTTLConfig string) error {
205205
return err
206206
}
207207

208-
// We create the pods concurrently to speed it up.
208+
// We precreate the pods (concurrently) to speed it up.
209+
forEachConcurrently(podsTTL, func(fnImage string, ttlStr string) {
210+
klog.Infof("preloading pod cache for function %v with TTL %v", fnImage, ttlStr)
211+
212+
ttl, err := time.ParseDuration(ttlStr)
213+
if err != nil {
214+
klog.Warningf("unable to parse duration from the config file for function %v: %w", fnImage, err)
215+
ttl = pcm.podTTL
216+
}
217+
218+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
219+
defer cancel()
220+
221+
// We invoke the function with useGenerateName=false so that the pod name is fixed,
222+
// since we want to ensure only one pod is created for each function.
223+
pcm.podManager.getFuncEvalPodClient(ctx, fnImage, ttl, false)
224+
klog.Infof("preloaded pod cache for function %v", fnImage)
225+
})
226+
227+
return nil
228+
}
229+
230+
// forEachConcurrently runs fn for each entry in the map m, in parallel goroutines.
231+
// It waits for each to finish before returning.
232+
func forEachConcurrently(m map[string]string, fn func(k string, v string)) {
209233
var wg sync.WaitGroup
210-
for fnImage, ttlStr := range podsTTL {
234+
for k, v := range m {
235+
k := k
236+
v := v
237+
211238
wg.Add(1)
212-
go func(img, ttlSt string) {
213-
klog.Infof("preloading pod cache for function %v with TTL %v", img, ttlSt)
239+
go func() {
214240
defer wg.Done()
215-
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
216-
defer cancel()
217-
ttl, err := time.ParseDuration(ttlSt)
218-
if err != nil {
219-
klog.Warningf("unable to parse duration from the config file for function %v: %w", fnImage, err)
220-
ttl = pcm.podTTL
221-
}
222-
// We invoke the function with useGenerateName=false so that the pod name is fixed,
223-
// since we want to ensure only one pod is created for each function.
224-
pcm.podManager.getFuncEvalPodClient(ctx, img, ttl, false)
225-
klog.Infof("preloaded pod cache for function %v", img)
226-
}(fnImage, ttlStr)
241+
fn(k, v)
242+
}()
227243
}
228-
// Wait for the cache warming up to finish before returning.
244+
// Wait for all the functions to complete.
229245
wg.Wait()
230-
return nil
231246
}
232247

233248
// podCacheManager responds to the requestCh and the podReadyCh and does the

0 commit comments

Comments
 (0)