Skip to content

Commit e138fd3

Browse files
committed
Removing CGO usage and adding better watcher handling at close
Signed-off-by: Amit Schendel <[email protected]>
1 parent 0dc94de commit e138fd3

File tree

2 files changed

+72
-57
lines changed

2 files changed

+72
-57
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ IMAGE_NAME ?= kapprofiler:latest
1414

1515

1616
$(BINARY_NAME): $(GOFILES) go.mod go.sum Makefile
17-
CGO_ENABLED=1 go build -o $(BINARY_NAME) -v
17+
CGO_ENABLED=0 go build -o $(BINARY_NAME) -v
1818

1919
test:
2020
$(GOTEST_SUDO_PREFIX) $(GOTEST) -v ./...

pkg/watcher/watcher.go

+71-56
Original file line numberDiff line numberDiff line change
@@ -90,69 +90,84 @@ func (w *Watcher) Start(notifyF WatchNotifyFunctions, gvr schema.GroupVersionRes
9090
}
9191
w.watcher = watcher
9292
w.running = true
93+
94+
// Use a context to gracefully stop the goroutine
95+
ctx, cancel := context.WithCancel(context.Background())
96+
defer cancel()
97+
9398
go func() {
9499
// Watch for events
100+
defer func() {
101+
// Ensure the watcher is closed when the goroutine exits
102+
watcher.Stop()
103+
}()
95104

96105
for {
97-
event, ok := <-watcher.ResultChan()
98-
if !ok {
99-
if w.running {
100-
// Need to restart the watcher: wait a bit and restart
101-
time.Sleep(5 * time.Second)
102-
listOptions.ResourceVersion = resourceVersion
103-
w.watcher, err = w.client.Resource(gvr).Namespace("").Watch(context.Background(), listOptions)
104-
if err != nil {
105-
log.Printf("watcher restart error: %v", err)
106+
select {
107+
case event, ok := <-watcher.ResultChan():
108+
if !ok {
109+
if w.running {
110+
// Need to restart the watcher: wait a bit and restart
111+
time.Sleep(5 * time.Second)
112+
listOptions.ResourceVersion = resourceVersion
113+
newWatcher, err := w.client.Resource(gvr).Namespace("").Watch(context.Background(), listOptions)
114+
if err != nil {
115+
log.Printf("watcher restart error: %v", err)
116+
return
117+
}
118+
w.watcher = newWatcher
119+
// Restart the loop
120+
continue
121+
} else {
122+
// Stop the watcher
123+
return
106124
}
107-
// Restart the loop
108-
continue
109-
} else {
110-
// Stop the watcher
111-
return
112-
}
113-
}
114-
switch event.Type {
115-
case watch.Added:
116-
// Convert the object to unstructured
117-
addedObject := event.Object.(*unstructured.Unstructured)
118-
if addedObject == nil {
119-
log.Printf("watcher error: addedObject is nil")
120-
continue
121-
}
122-
// Update the resourceVersion
123-
if addedObject.GetResourceVersion() > resourceVersion {
124-
resourceVersion = addedObject.GetResourceVersion()
125-
}
126-
notifyF.AddFunc(addedObject)
127-
addedObject = nil // Make sure the item is scraped by the GC
128-
case watch.Modified:
129-
// Convert the object to unstructured
130-
modifiedObject := event.Object.(*unstructured.Unstructured)
131-
if modifiedObject == nil {
132-
log.Printf("watcher error: modifiedObject is nil")
133-
continue
134-
}
135-
// Update the resourceVersion
136-
if modifiedObject.GetResourceVersion() > resourceVersion {
137-
resourceVersion = modifiedObject.GetResourceVersion()
138-
}
139-
notifyF.UpdateFunc(modifiedObject)
140-
modifiedObject = nil // Make sure the item is scraped by the GC
141-
case watch.Deleted:
142-
// Convert the object to unstructured
143-
deletedObject := event.Object.(*unstructured.Unstructured)
144-
if deletedObject == nil {
145-
log.Printf("watcher error: deletedObject is nil")
146-
continue
147125
}
148-
// Update the resourceVersion
149-
if deletedObject.GetResourceVersion() > resourceVersion {
150-
resourceVersion = deletedObject.GetResourceVersion()
126+
127+
switch event.Type {
128+
case watch.Added:
129+
// Convert the object to unstructured
130+
addedObject := event.Object.(*unstructured.Unstructured)
131+
if addedObject == nil {
132+
log.Printf("watcher error: addedObject is nil")
133+
continue
134+
}
135+
// Update the resourceVersion
136+
if addedObject.GetResourceVersion() > resourceVersion {
137+
resourceVersion = addedObject.GetResourceVersion()
138+
}
139+
notifyF.AddFunc(addedObject)
140+
case watch.Modified:
141+
// Convert the object to unstructured
142+
modifiedObject := event.Object.(*unstructured.Unstructured)
143+
if modifiedObject == nil {
144+
log.Printf("watcher error: modifiedObject is nil")
145+
continue
146+
}
147+
// Update the resourceVersion
148+
if modifiedObject.GetResourceVersion() > resourceVersion {
149+
resourceVersion = modifiedObject.GetResourceVersion()
150+
}
151+
notifyF.UpdateFunc(modifiedObject)
152+
case watch.Deleted:
153+
// Convert the object to unstructured
154+
deletedObject := event.Object.(*unstructured.Unstructured)
155+
if deletedObject == nil {
156+
log.Printf("watcher error: deletedObject is nil")
157+
continue
158+
}
159+
// Update the resourceVersion
160+
if deletedObject.GetResourceVersion() > resourceVersion {
161+
resourceVersion = deletedObject.GetResourceVersion()
162+
}
163+
notifyF.DeleteFunc(deletedObject)
164+
case watch.Error:
165+
log.Printf("watcher error: %v", event.Object)
151166
}
152-
notifyF.DeleteFunc(deletedObject)
153-
deletedObject = nil // Make sure the item is scraped by the GC
154-
case watch.Error:
155-
log.Printf("watcher error: %v", event.Object)
167+
168+
case <-ctx.Done():
169+
// Exit the goroutine when the context is canceled
170+
return
156171
}
157172
}
158173
}()

0 commit comments

Comments
 (0)