Skip to content

Commit b14b7b4

Browse files
committed
address review comments
Signed-off-by: Lionel Villard <villard@us.ibm.com>
1 parent 896bf7b commit b14b7b4

File tree

5 files changed

+54
-41
lines changed

5 files changed

+54
-41
lines changed

Dockerfile.activator

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
1-
## Multistage build
1+
# Build Stage: using Go 1.25 image
22
FROM quay.io/projectquay/golang:1.25 AS builder
3-
ARG COMMIT_SHA=unknown
4-
ARG BUILD_REF
5-
ARG TARGETOS=linux
6-
ARG TARGETARCH=amd64
7-
ENV CGO_ENABLED=0
8-
ENV GOOS=$TARGETOS
9-
ENV GOARCH=$TARGETARCH
3+
ARG TARGETOS
4+
ARG TARGETARCH
105

11-
# Dependencies
12-
WORKDIR /src
13-
COPY go.mod go.sum ./
14-
RUN go mod download
6+
WORKDIR /workspace
157

16-
# Sources
8+
# Copy the Go Modules manifests
9+
COPY go.mod go.mod
10+
COPY go.sum go.sum
11+
12+
# Copy the go source
1713
COPY cmd/activator ./cmd/activator
1814
COPY pkg/activator ./pkg/activator
19-
WORKDIR /src/cmd/activator
20-
RUN go build -ldflags="-X sigs.k8s.io/gateway-api-inference-extension/version.CommitSHA=${COMMIT_SHA} -X sigs.k8s.io/gateway-api-inference-extension/version.BuildRef=${BUILD_REF}" -o /activator
2115

22-
## Multistage deploy
23-
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
16+
# Build
17+
# the GOARCH has not a default value to allow the binary be built according to the host where the command
18+
# was called. For example, if we call make image-build in a local env which has the Apple Silicon M1 SO
19+
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
20+
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
21+
ENV CGO_ENABLED=0
22+
ENV GOOS=${TARGETOS:-linux}
23+
ENV GOARCH=${TARGETARCH}
24+
ARG COMMIT_SHA=unknown
25+
ARG BUILD_REF
26+
RUN go build -a -o bin/activator -ldflags="-X sigs.k8s.io/gateway-api-inference-extension/version.CommitSHA=${COMMIT_SHA} -X sigs.k8s.io/gateway-api-inference-extension/version.BuildRef=${BUILD_REF}" cmd/activator/main.go
27+
2428

29+
# Use ubi9 as a minimal base image to package the manager binary
30+
# Refer to https://catalog.redhat.com/software/containers/ubi9/ubi-minimal/615bd9b4075b022acc111bf5 for more details
31+
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
2532
WORKDIR /
26-
COPY --from=builder /activator /activator
33+
COPY --from=builder /workspace/bin/activator /app/activator
34+
35+
# expose gRPC, health and metrics ports
36+
EXPOSE 9002
37+
EXPOSE 9003
38+
EXPOSE 9090
39+
40+
USER 65532:65532
2741

28-
ENTRYPOINT ["/activator"]
42+
ENTRYPOINT ["/app/activator"]

Dockerfile.epp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Build Stage: using Go 1.24.1 image
1+
# Build Stage: using Go 1.25 image
22
FROM quay.io/projectquay/golang:1.25 AS builder
33
ARG TARGETOS
44
ARG TARGETARCH

cmd/activator/runner/runner.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func Run(ctx context.Context) error {
7575
flag.Parse()
7676
initLogging(&opts)
7777

78-
setupLog.Info("GIE build", "commit-sha", version.CommitSHA, "build-ref", version.BuildRef)
78+
setupLog.Info("Activator build", "commit-sha", version.CommitSHA, "build-ref", version.BuildRef)
7979

8080
// Validate flags
8181
if err := validateFlags(); err != nil {
@@ -109,7 +109,7 @@ func Run(ctx context.Context) error {
109109

110110
// --- Setup Deactivator ---
111111
if *enableScaleToZero {
112-
deactivator, err := requestcontrol.DeactivatorWithConfig(cfg, &datastore)
112+
deactivator, err := requestcontrol.DeactivatorWithConfig(cfg, datastore)
113113
if err != nil {
114114
setupLog.Error(err, "Failed to setup Deactivator")
115115
return err

pkg/activator/datastore/datastore.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type Datastore interface {
4141
PoolGet() (*v1.InferencePool, error)
4242
PoolHasSynced() bool
4343

44-
GetTicker() *time.Ticker
44+
GetTickerCh() <-chan time.Time
4545
ResetTicker(t time.Duration)
4646
StopTicker()
4747

@@ -52,16 +52,13 @@ type Datastore interface {
5252
// NewDatastore creates a new Datastore instance with the provided parent context.
5353
func NewDatastore(parentCtx context.Context) Datastore {
5454
store := &datastore{
55-
parentCtx: parentCtx,
56-
poolMu: sync.RWMutex{},
57-
ticker: time.NewTicker(60 * time.Second),
55+
poolMu: sync.RWMutex{},
56+
ticker: time.NewTicker(60 * time.Second),
5857
}
5958
return store
6059
}
6160

6261
type datastore struct {
63-
// parentCtx controls the lifecycle of the background metrics goroutines that spawn up by the datastore.
64-
parentCtx context.Context
6562
// poolMu is used to synchronize access to pool map.
6663
poolMu sync.RWMutex
6764
pool *v1.InferencePool
@@ -79,7 +76,7 @@ func (ds *datastore) PoolSet(pool *v1.InferencePool) {
7976
func (ds *datastore) PoolGet() (*v1.InferencePool, error) {
8077
ds.poolMu.RLock()
8178
defer ds.poolMu.RUnlock()
82-
if !ds.PoolHasSynced() {
79+
if ds.pool == nil {
8380
return nil, errPoolNotSynced
8481
}
8582
return ds.pool, nil
@@ -96,19 +93,19 @@ func (ds *datastore) Clear() {
9693
}
9794

9895
func (ds *datastore) ResetTicker(t time.Duration) {
99-
ds.poolMu.RLock()
100-
defer ds.poolMu.RUnlock()
96+
ds.poolMu.Lock()
97+
defer ds.poolMu.Unlock()
10198
ds.ticker.Reset(t)
10299
}
103100

104-
func (ds *datastore) GetTicker() *time.Ticker {
101+
func (ds *datastore) GetTickerCh() <-chan time.Time {
105102
ds.poolMu.RLock()
106103
defer ds.poolMu.RUnlock()
107-
return ds.ticker
104+
return ds.ticker.C
108105
}
109106

110107
func (ds *datastore) StopTicker() {
111-
ds.poolMu.RLock()
112-
defer ds.poolMu.RUnlock()
108+
ds.poolMu.Lock()
109+
defer ds.poolMu.Unlock()
113110
ds.ticker.Stop()
114111
}

pkg/activator/requestcontrol/deactivator.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ type Deactivator struct {
2626
DynamicClient *dynamic.DynamicClient
2727
ScaleClient scale.ScalesGetter
2828
Mapper meta.RESTMapper
29-
datastore *datastore.Datastore
29+
datastore datastore.Datastore
3030
}
3131

3232
// DeactivatorWithConfig creates a new Deactivator with the provided REST config and Datastore.
33-
func DeactivatorWithConfig(config *rest.Config, datastore *datastore.Datastore) (*Deactivator, error) {
33+
func DeactivatorWithConfig(config *rest.Config, datastore datastore.Datastore) (*Deactivator, error) {
3434
scaleClient, mapper, err := initScaleClient(config)
3535
if err != nil {
3636
return nil, err
@@ -51,20 +51,22 @@ func DeactivatorWithConfig(config *rest.Config, datastore *datastore.Datastore)
5151
// MonitorInferencePoolIdleness monitors the InferencePool for idleness and scales it down to zero replicas
5252
func (da *Deactivator) MonitorInferencePoolIdleness(ctx context.Context) {
5353
logger := log.FromContext(ctx)
54-
ds := *(da.datastore)
54+
ds := da.datastore
5555

56+
// The deactivator uses a ticker to periodically try and scale down the InferencePool after idleness.
57+
// Upon each received requests, the ticker is reset to delay the next scale-down check.
5658
ds.ResetTicker(DefaultScaleDownDelay)
5759
defer ds.StopTicker()
5860

59-
ticker := ds.GetTicker()
61+
tickerCh := ds.GetTickerCh()
6062

6163
for {
6264
select {
6365
case <-ctx.Done():
6466
logger.Info("Context cancelled, stopping deactivator")
6567
return
66-
case <-ticker.C:
67-
logger.V(logutil.DEBUG).Info("Deactivator Time check for inferencePool idleness: " + time.Now().Format("15:04:05"))
68+
case <-tickerCh:
69+
logger.V(logutil.DEBUG).Info("Deactivator time check for inferencePool idleness: " + time.Now().Format("15:04:05"))
6870

6971
// Get InferencePool Info
7072
pool, err := ds.PoolGet()

0 commit comments

Comments
 (0)