@@ -40,8 +40,11 @@ import (
4040 "k8s.io/client-go/tools/cache"
4141 "k8s.io/klog/v2"
4242
43+ fmav1alpha1 "github.com/llm-d-incubation/llm-d-fast-model-actuation/api/fma/v1alpha1"
4344 "github.com/llm-d-incubation/llm-d-fast-model-actuation/pkg/api"
4445 genctlr "github.com/llm-d-incubation/llm-d-fast-model-actuation/pkg/controller/generic"
46+ fmainformers "github.com/llm-d-incubation/llm-d-fast-model-actuation/pkg/generated/informers/externalversions"
47+ fmalisters "github.com/llm-d-incubation/llm-d-fast-model-actuation/pkg/generated/listers/fma/v1alpha1"
4548)
4649
4750// This package implements the dual-pods controller.
@@ -147,6 +150,7 @@ func (config ControllerConfig) NewController(
147150 coreClient coreclient.CoreV1Interface ,
148151 namespace string ,
149152 corev1PreInformers corev1preinformers.Interface ,
153+ fmaInformerFactory fmainformers.SharedInformerFactory ,
150154) (* controller , error ) {
151155 ctl := & controller {
152156 enqueueLogger : logger .WithName (ControllerName ),
@@ -158,16 +162,21 @@ func (config ControllerConfig) NewController(
158162 cmLister : corev1PreInformers .ConfigMaps ().Lister (),
159163 nodeInformer : corev1PreInformers .Nodes ().Informer (),
160164 nodeLister : corev1PreInformers .Nodes ().Lister (),
165+ iscInformer : fmaInformerFactory .Fma ().V1alpha1 ().InferenceServerConfigs ().Informer (),
166+ iscLister : fmaInformerFactory .Fma ().V1alpha1 ().InferenceServerConfigs ().Lister (),
167+ lcInformer : fmaInformerFactory .Fma ().V1alpha1 ().LauncherConfigs ().Informer (),
168+ lcLister : fmaInformerFactory .Fma ().V1alpha1 ().LauncherConfigs ().Lister (),
161169 sleeperLimit : config .SleeperLimit ,
162170 debugAccelMemory : config .AcceleratorSleepingMemoryLimitMiB < math .MaxInt32 ,
163171 accelMemoryLimitMiB : config .AcceleratorSleepingMemoryLimitMiB ,
164172 nodeNameToData : map [string ]* nodeData {},
165173 }
166174 ctl .gpuMap .Store (& map [string ]GpuLocation {})
167175 err := ctl .podInformer .AddIndexers (cache.Indexers {
168- requesterIndexName : requesterIndexFunc ,
169- nominalHashIndexName : nominalHashIndexFunc ,
170- GPUIndexName : GPUIndexFunc })
176+ inferenceServerConfigIndexName : inferenceServerConfigIndexFunc ,
177+ requesterIndexName : requesterIndexFunc ,
178+ nominalHashIndexName : nominalHashIndexFunc ,
179+ GPUIndexName : GPUIndexFunc })
171180 if err != nil { //impossible
172181 return nil , err
173182 }
@@ -194,6 +203,14 @@ func (config ControllerConfig) NewController(
194203 if err != nil {
195204 panic (err )
196205 }
206+ _ , err = ctl .iscInformer .AddEventHandler (ctl )
207+ if err != nil {
208+ panic (err )
209+ }
210+ _ , err = ctl .lcInformer .AddEventHandler (ctl )
211+ if err != nil {
212+ panic (err )
213+ }
197214 return ctl , nil
198215}
199216
@@ -207,6 +224,10 @@ type controller struct {
207224 cmLister corev1listers.ConfigMapLister
208225 nodeInformer cache.SharedIndexInformer
209226 nodeLister corev1listers.NodeLister
227+ iscInformer cache.SharedIndexInformer
228+ iscLister fmalisters.InferenceServerConfigLister
229+ lcInformer cache.SharedIndexInformer
230+ lcLister fmalisters.LauncherConfigLister
210231 genctlr.KnowsProcessedSync [queueItem ]
211232
212233 sleeperLimit int
@@ -327,7 +348,7 @@ const (
327348// The controller cares about server-requesting Pods, bound direct server-providing Pods, and launcher-based server-providing Pods.
328349// The controller doesn't care about unbound direct providers and other Pods.
329350func careAbout (pod * corev1.Pod ) (item infSvrItem , it infSvrItemType ) {
330- if len (pod .Annotations [api .ServerPatchAnnotationName ]) > 0 {
351+ if len (pod .Annotations [api .ServerPatchAnnotationName ]) > 0 || len ( pod . Annotations [ api . InferenceServerConfigAnnotationName ]) > 0 {
331352 return infSvrItem {pod .UID , pod .Name }, infSvrItemRequester
332353 }
333354 requesterStr := pod .Annotations [requesterAnnotationKey ]
@@ -338,6 +359,17 @@ func careAbout(pod *corev1.Pod) (item infSvrItem, it infSvrItemType) {
338359 return infSvrItem {apitypes .UID (requesterParts [0 ]), requesterParts [1 ]}, infSvrItemBoundDirectProvider
339360}
340361
362+ const inferenceServerConfigIndexName = "inferenceserverconfig"
363+
364+ func inferenceServerConfigIndexFunc (obj any ) ([]string , error ) {
365+ pod := obj .(* corev1.Pod )
366+ inferenceServerConfigName := pod .Annotations [api .InferenceServerConfigAnnotationName ]
367+ if len (inferenceServerConfigName ) == 0 {
368+ return []string {}, nil
369+ }
370+ return []string {inferenceServerConfigName }, nil
371+ }
372+
341373const requesterIndexName = "requester"
342374
343375func requesterIndexFunc (obj any ) ([]string , error ) {
@@ -373,6 +405,8 @@ func (ctl *controller) OnAdd(obj any, isInInitialList bool) {
373405 nd .add (item )
374406 ctl .Queue .Add (nodeItem {nodeName })
375407 }
408+ case * fmav1alpha1.InferenceServerConfig :
409+ ctl .enqueueRequestersByInferenceServerConfig (typed , isInInitialList )
376410 case * corev1.ConfigMap :
377411 if typed .Name != GPUMapName {
378412 ctl .enqueueLogger .V (5 ).Info ("Ignoring ConfigMap that is not the GPU map" , "ref" , cache .MetaObjectToName (typed ))
@@ -412,6 +446,8 @@ func (ctl *controller) OnUpdate(prev, obj any) {
412446 nd .add (item )
413447 ctl .Queue .Add (nodeItem {nodeName })
414448 }
449+ case * fmav1alpha1.InferenceServerConfig :
450+ ctl .enqueueRequestersByInferenceServerConfig (typed , false )
415451 case * corev1.ConfigMap :
416452 if typed .Name != GPUMapName {
417453 ctl .enqueueLogger .V (5 ).Info ("Ignoring ConfigMap that is not the GPU map" , "ref" , cache .MetaObjectToName (typed ))
@@ -454,6 +490,8 @@ func (ctl *controller) OnDelete(obj any) {
454490 nd .add (item )
455491 ctl .Queue .Add (nodeItem {nodeName })
456492 }
493+ case * fmav1alpha1.InferenceServerConfig :
494+ ctl .enqueueRequestersByInferenceServerConfig (typed , false )
457495 case * corev1.ConfigMap :
458496 if typed .Name != GPUMapName {
459497 ctl .enqueueLogger .V (5 ).Info ("Ignoring ConfigMap that is not the GPU map" , "ref" , cache .MetaObjectToName (typed ))
@@ -478,7 +516,7 @@ func getProviderNodeName(pod *corev1.Pod) (string, error) {
478516}
479517
480518func (ctl * controller ) Start (ctx context.Context ) error {
481- if ! cache .WaitForNamedCacheSync (ControllerName , ctx .Done (), ctl .cmInformer .HasSynced , ctl .podInformer .HasSynced , ctl .nodeInformer .HasSynced ) {
519+ if ! cache .WaitForNamedCacheSync (ControllerName , ctx .Done (), ctl .cmInformer .HasSynced , ctl .podInformer .HasSynced , ctl .nodeInformer .HasSynced , ctl . iscInformer . HasSynced , ctl . lcInformer . HasSynced ) {
482520 return fmt .Errorf ("caches not synced before end of Start context" )
483521 }
484522 err := ctl .StartWorkers (ctx )
@@ -550,6 +588,37 @@ func (ctl *controller) enqueueRequesters(ctx context.Context) {
550588 }
551589}
552590
591+ func (ctl * controller ) enqueueRequestersByInferenceServerConfig (isc * fmav1alpha1.InferenceServerConfig , isInInitialList bool ) {
592+ inferenceServerConfigName := isc .Name
593+ requesters , err := ctl .podInformer .GetIndexer ().ByIndex (inferenceServerConfigIndexName , inferenceServerConfigName )
594+ if err != nil {
595+ ctl .enqueueLogger .Error (err , "Failed to get server requesting pods that use InferenceServerConfig" , "ref" , cache .MetaObjectToName (isc ))
596+ return
597+ }
598+ nodeNames := sets .New [string ]()
599+ for _ , podObj := range requesters {
600+ pod := podObj .(* corev1.Pod )
601+ item , it := careAbout (pod )
602+ if it != infSvrItemRequester {
603+ // should not happen because of the nature of inferenceServerConfigIndexFunc
604+ ctl .enqueueLogger .V (5 ).Info ("Ignoring Pod that is not a server-requesting Pod" , "pod" , pod .Name )
605+ continue
606+ }
607+ nodeName := pod .Spec .NodeName
608+ if nodeName == "" {
609+ ctl .enqueueLogger .V (5 ).Info ("Ignoring non-scheduled server-requesting Pod that uses InferenceServerConfig" , "pod" , pod .Name , "inferenceServerConfigName" , inferenceServerConfigName )
610+ continue
611+ }
612+ nd := ctl .getNodeData (nodeName )
613+ ctl .enqueueLogger .V (5 ).Info ("Enqueuing inference server reference due to notification of InferenceServerConfig" , "nodeName" , nodeName , "item" , item , "infSvrItemType" , it , "inferenceServerConfigName" , inferenceServerConfigName , "isInInitialList" , isInInitialList , "resourceVersion" , isc .ResourceVersion )
614+ nd .add (item )
615+ nodeNames .Insert (nodeName )
616+ }
617+ for nodeName := range nodeNames {
618+ ctl .Queue .Add (nodeItem {nodeName })
619+ }
620+ }
621+
553622func (ctl * controller ) getNodeData (nodeName string ) * nodeData {
554623 ctl .mutex .Lock ()
555624 defer ctl .mutex .Unlock ()
0 commit comments