@@ -17,6 +17,7 @@ limitations under the License.
17
17
package main
18
18
19
19
import (
20
+ "context"
20
21
"flag"
21
22
"fmt"
22
23
"net"
@@ -40,8 +41,10 @@ import (
40
41
"sigs.k8s.io/gateway-api-inference-extension/internal/runnable"
41
42
backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
42
43
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datastore"
44
+ "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontroller"
43
45
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
44
46
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics/collectors"
47
+ "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/saturationdetector"
45
48
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling"
46
49
runserver "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/server"
47
50
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
@@ -136,13 +139,20 @@ func run() error {
136
139
})
137
140
setupLog .Info ("Flags processed" , "flags" , flags )
138
141
139
- // Init runtime.
142
+ // --- Load Configurations from Environment Variables ---
143
+ // Note: Scheduler config is loaded via its package init currently. We may
144
+ // want to load it here explicitly:
145
+ fcConfig , flowControllerEnabled := flowcontroller .LoadConfigFromEnv ()
146
+ sdConfig := saturationdetector .LoadConfigFromEnv ()
147
+
148
+ // --- Get Kubernetes Config ---
140
149
cfg , err := ctrl .GetConfig ()
141
150
if err != nil {
142
- setupLog .Error (err , "Failed to get rest config" )
151
+ setupLog .Error (err , "Failed to get Kubernetes rest config" )
143
152
return err
144
153
}
145
154
155
+ // --- Setup Manager ---
146
156
poolNamespacedName := types.NamespacedName {
147
157
Name : * poolName ,
148
158
Namespace : * poolNamespace ,
@@ -153,7 +163,7 @@ func run() error {
153
163
return err
154
164
}
155
165
156
- // Set up mapper for metric scraping.
166
+ // --- Setup Datastore ---
157
167
mapping , err := backendmetrics .NewMetricMapping (
158
168
* totalQueuedRequestsMetric ,
159
169
* kvCacheUsagePercentageMetric ,
@@ -164,47 +174,82 @@ func run() error {
164
174
return err
165
175
}
166
176
verifyMetricMapping (* mapping , setupLog )
167
-
168
177
pmf := backendmetrics .NewPodMetricsFactory (& backendmetrics.PodMetricsClientImpl {MetricMapping : mapping }, * refreshMetricsInterval )
169
- // Setup runner.
170
178
ctx := ctrl .SetupSignalHandler ()
179
+ appDatastore := datastore .NewDatastore (ctx , pmf )
171
180
172
- datastore := datastore .NewDatastore (ctx , pmf )
181
+ // --- Initialize EPP Components ---
182
+ appScheduler := scheduling .NewScheduler (appDatastore )
183
+
184
+ appSaturationDetector , err := saturationdetector .NewDetector (
185
+ * sdConfig ,
186
+ appDatastore ,
187
+ ctrl .Log .WithName ("saturation-detector" ),
188
+ )
189
+ if err != nil {
190
+ setupLog .Error (err , "Failed to create SaturationDetector" )
191
+ return err
192
+ }
173
193
174
- scheduler := scheduling .NewScheduler (datastore )
194
+ var appFlowController * flowcontroller.FlowController
195
+ if flowControllerEnabled {
196
+ appFlowController , err = flowcontroller .NewFlowController (
197
+ appSaturationDetector ,
198
+ fcConfig ,
199
+ )
200
+ if err != nil {
201
+ setupLog .Error (err , "Failed to create FlowController" )
202
+ return err
203
+ }
204
+ setupLog .Info ("FlowController enabled and initialized." )
205
+ } else {
206
+ setupLog .Info ("FlowController is disabled via configuration." )
207
+ }
208
+
209
+ // --- Setup ExtProc Server Runner ---
175
210
serverRunner := & runserver.ExtProcServerRunner {
176
211
GrpcPort : * grpcPort ,
177
212
DestinationEndpointHintMetadataNamespace : * destinationEndpointHintMetadataNamespace ,
178
213
DestinationEndpointHintKey : * destinationEndpointHintKey ,
179
214
PoolNamespacedName : poolNamespacedName ,
180
- Datastore : datastore ,
215
+ Datastore : appDatastore ,
181
216
SecureServing : * secureServing ,
182
217
CertPath : * certPath ,
183
218
RefreshPrometheusMetricsInterval : * refreshPrometheusMetricsInterval ,
184
- Scheduler : scheduler ,
219
+ Scheduler : appScheduler ,
220
+ FlowController : appFlowController , // Pass instance (can be nil)
221
+ SaturationDetector : appSaturationDetector ,
222
+ FlowControllerEnabled : flowControllerEnabled ,
185
223
}
186
224
if err := serverRunner .SetupWithManager (ctx , mgr ); err != nil {
187
- setupLog .Error (err , "Failed to setup ext-proc controllers" )
225
+ setupLog .Error (err , "Failed to setup EPP controllers" )
226
+ return err
227
+ }
228
+
229
+ // --- Add Runnables to Manager ---
230
+
231
+ // Register FlowController Run loop.
232
+ if err := registerFlowController (mgr , appFlowController ); err != nil {
188
233
return err
189
234
}
190
235
191
236
// Register health server.
192
- if err := registerHealthServer (mgr , ctrl .Log .WithName ("health" ), datastore , * grpcHealthPort ); err != nil {
237
+ if err := registerHealthServer (mgr , ctrl .Log .WithName ("health" ), appDatastore , * grpcHealthPort ); err != nil {
193
238
return err
194
239
}
195
240
196
241
// Register ext-proc server.
197
- if err := mgr .Add (serverRunner .AsRunnable (ctrl .Log .WithName ("ext-proc" ))); err != nil {
198
- setupLog .Error (err , "Failed to register ext-proc gRPC server" )
242
+ if err := registerExtProcServer (mgr , serverRunner , ctrl .Log .WithName ("ext-proc" )); err != nil {
199
243
return err
200
244
}
201
245
202
246
// Register metrics handler.
203
- if err := registerMetricsHandler (mgr , * metricsPort , cfg , datastore ); err != nil {
247
+ if err := registerMetricsHandler (mgr , * metricsPort , cfg , appDatastore ); err != nil {
204
248
return err
205
249
}
206
250
207
- // Start the manager. This blocks until a signal is received.
251
+ // --- Start Manager ---
252
+ // This blocks until a signal is received.
208
253
setupLog .Info ("Controller manager starting" )
209
254
if err := mgr .Start (ctx ); err != nil {
210
255
setupLog .Error (err , "Error starting controller manager" )
@@ -232,6 +277,39 @@ func initLogging(opts *zap.Options) {
232
277
ctrl .SetLogger (logger )
233
278
}
234
279
280
+ // registerFlowController adds the FlowController Run loop as a Runnable to the
281
+ // manager.
282
+ func registerFlowController (mgr manager.Manager , fc * flowcontroller.FlowController ) error {
283
+ if fc == nil {
284
+ setupLog .Info ("FlowController is nil (disabled), skipping registration." )
285
+ return nil // Not an error if it's intentionally disabled
286
+ }
287
+ if err := mgr .Add (manager .RunnableFunc (func (runCtx context.Context ) error {
288
+ fcLog := ctrl .Log .WithName ("flowcontroller-runnable" )
289
+ fcLog .Info ("Starting FlowController Run loop" )
290
+ // Run the FlowController; it handles context cancellation internally.
291
+ fc .Run (runCtx )
292
+ fcLog .Info ("FlowController Run loop stopped" )
293
+ return nil
294
+ })); err != nil {
295
+ setupLog .Error (err , "Failed to add FlowController runnable to manager" )
296
+ return err
297
+ }
298
+ setupLog .Info ("FlowController Run loop added to manager." )
299
+ return nil
300
+ }
301
+
302
+ // registerExtProcServer adds the ExtProcServerRunner as a Runnable to the
303
+ // manager.
304
+ func registerExtProcServer (mgr manager.Manager , runner * runserver.ExtProcServerRunner , logger logr.Logger ) error {
305
+ if err := mgr .Add (runner .AsRunnable (logger )); err != nil {
306
+ setupLog .Error (err , "Failed to register ext-proc gRPC server runnable" )
307
+ return err
308
+ }
309
+ setupLog .Info ("ExtProc server runner added to manager." )
310
+ return nil
311
+ }
312
+
235
313
// registerHealthServer adds the Health gRPC server as a Runnable to the given manager.
236
314
func registerHealthServer (mgr manager.Manager , logger logr.Logger , ds datastore.Datastore , port int ) error {
237
315
srv := grpc .NewServer ()
@@ -321,5 +399,4 @@ func verifyMetricMapping(mapping backendmetrics.MetricMapping, logger logr.Logge
321
399
if mapping .LoraRequestInfo == nil {
322
400
logger .Info ("Not scraping metric: LoraRequestInfo" )
323
401
}
324
-
325
402
}
0 commit comments