Skip to content

Commit ebfce38

Browse files
committed
refactor: use informer in webhook handler to reduce memory usage
Signed-off-by: Alexander Matyushentsev <[email protected]>
1 parent 6ca71fe commit ebfce38

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,7 @@ func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWeb
12571257

12581258
// Webhook handler for git events (Note: cache timeouts are hardcoded because API server does not write to cache and not really using them)
12591259
argoDB := db.NewDB(server.Namespace, server.settingsMgr, server.KubeClientset)
1260-
acdWebhookHandler := webhook.NewHandler(server.Namespace, server.ApplicationNamespaces, server.WebhookParallelism, server.AppClientset, server.settings, server.settingsMgr, server.RepoServerCache, server.Cache, argoDB, server.settingsMgr.GetMaxWebhookPayloadSize())
1260+
acdWebhookHandler := webhook.NewHandler(server.Namespace, server.ApplicationNamespaces, server.WebhookParallelism, server.AppClientset, server.appLister, server.settings, server.settingsMgr, server.RepoServerCache, server.Cache, argoDB, server.settingsMgr.GetMaxWebhookPayloadSize())
12611261

12621262
mux.HandleFunc("/api/webhook", acdWebhookHandler.Handler)
12631263

util/webhook/webhook.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,11 @@ import (
1212
"sync"
1313
"time"
1414

15+
alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1"
1516
bb "github.com/ktrysmt/go-bitbucket"
17+
"k8s.io/apimachinery/pkg/labels"
1618

1719
"github.com/Masterminds/semver/v3"
18-
"github.com/go-playground/webhooks/v6/azuredevops"
19-
"github.com/go-playground/webhooks/v6/bitbucket"
20-
bitbucketserver "github.com/go-playground/webhooks/v6/bitbucket-server"
21-
"github.com/go-playground/webhooks/v6/github"
22-
"github.com/go-playground/webhooks/v6/gitlab"
23-
"github.com/go-playground/webhooks/v6/gogs"
24-
gogsclient "github.com/gogits/go-gogs-client"
25-
log "github.com/sirupsen/logrus"
26-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27-
2820
"github.com/argoproj/argo-cd/v3/common"
2921
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
3022
appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned"
@@ -36,6 +28,14 @@ import (
3628
"github.com/argoproj/argo-cd/v3/util/git"
3729
"github.com/argoproj/argo-cd/v3/util/glob"
3830
"github.com/argoproj/argo-cd/v3/util/settings"
31+
"github.com/go-playground/webhooks/v6/azuredevops"
32+
"github.com/go-playground/webhooks/v6/bitbucket"
33+
bitbucketserver "github.com/go-playground/webhooks/v6/bitbucket-server"
34+
"github.com/go-playground/webhooks/v6/github"
35+
"github.com/go-playground/webhooks/v6/gitlab"
36+
"github.com/go-playground/webhooks/v6/gogs"
37+
gogsclient "github.com/gogits/go-gogs-client"
38+
log "github.com/sirupsen/logrus"
3939
)
4040

4141
type settingsSource interface {
@@ -60,6 +60,7 @@ type ArgoCDWebhookHandler struct {
6060
ns string
6161
appNs []string
6262
appClientset appclientset.Interface
63+
appsLister alpha1.ApplicationLister
6364
github *github.Webhook
6465
gitlab *gitlab.Webhook
6566
bitbucket *bitbucket.Webhook
@@ -72,7 +73,7 @@ type ArgoCDWebhookHandler struct {
7273
maxWebhookPayloadSizeB int64
7374
}
7475

75-
func NewHandler(namespace string, applicationNamespaces []string, webhookParallelism int, appClientset appclientset.Interface, set *settings.ArgoCDSettings, settingsSrc settingsSource, repoCache *cache.Cache, serverCache *servercache.Cache, argoDB db.ArgoDB, maxWebhookPayloadSizeB int64) *ArgoCDWebhookHandler {
76+
func NewHandler(namespace string, applicationNamespaces []string, webhookParallelism int, appClientset appclientset.Interface, appsLister alpha1.ApplicationLister, set *settings.ArgoCDSettings, settingsSrc settingsSource, repoCache *cache.Cache, serverCache *servercache.Cache, argoDB db.ArgoDB, maxWebhookPayloadSizeB int64) *ArgoCDWebhookHandler {
7677
githubWebhook, err := github.New(github.Options.Secret(set.GetWebhookGitHubSecret()))
7778
if err != nil {
7879
log.Warnf("Unable to init the GitHub webhook")
@@ -115,6 +116,7 @@ func NewHandler(namespace string, applicationNamespaces []string, webhookParalle
115116
db: argoDB,
116117
queue: make(chan any, payloadQueueSize),
117118
maxWebhookPayloadSizeB: maxWebhookPayloadSizeB,
119+
appsLister: appsLister,
118120
}
119121

120122
acdWebhook.startWorkerPool(webhookParallelism)
@@ -313,8 +315,8 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) {
313315
nsFilter = ""
314316
}
315317

316-
appIf := a.appClientset.ArgoprojV1alpha1().Applications(nsFilter)
317-
apps, err := appIf.List(context.Background(), metav1.ListOptions{})
318+
appIf := a.appsLister.Applications(nsFilter)
319+
apps, err := appIf.List(labels.Everything())
318320
if err != nil {
319321
log.Warnf("Failed to list applications: %v", err)
320322
return
@@ -339,9 +341,9 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) {
339341
// Skip any application that is neither in the control plane's namespace
340342
// nor in the list of enabled namespaces.
341343
var filteredApps []v1alpha1.Application
342-
for _, app := range apps.Items {
344+
for _, app := range apps {
343345
if app.Namespace == a.ns || glob.MatchStringInList(a.appNs, app.Namespace, glob.REGEXP) {
344-
filteredApps = append(filteredApps, app)
346+
filteredApps = append(filteredApps, *app)
345347
}
346348
}
347349

util/webhook/webhook_test.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
bb "github.com/ktrysmt/go-bitbucket"
1919
"github.com/stretchr/testify/mock"
20+
"k8s.io/apimachinery/pkg/labels"
2021
"k8s.io/apimachinery/pkg/types"
2122

2223
"github.com/go-playground/webhooks/v6/bitbucket"
@@ -28,6 +29,7 @@ import (
2829
"k8s.io/apimachinery/pkg/runtime"
2930
kubetesting "k8s.io/client-go/testing"
3031

32+
argov1 "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1"
3133
servercache "github.com/argoproj/argo-cd/v3/server/cache"
3234
"github.com/argoproj/argo-cd/v3/util/cache/appstate"
3335
"github.com/argoproj/argo-cd/v3/util/db"
@@ -98,6 +100,31 @@ func NewMockHandlerForBitbucketCallback(reactor *reactorDef, applicationNamespac
98100
return newMockHandler(reactor, applicationNamespaces, defaultMaxPayloadSize, &mockDB, &argoSettings, objects...)
99101
}
100102

103+
type fakeAppsLister struct {
104+
argov1.ApplicationLister
105+
argov1.ApplicationNamespaceLister
106+
namespace string
107+
clientset *appclientset.Clientset
108+
}
109+
110+
func (f *fakeAppsLister) Applications(namespace string) argov1.ApplicationNamespaceLister {
111+
return &fakeAppsLister{namespace: namespace, clientset: f.clientset}
112+
}
113+
114+
func (f *fakeAppsLister) List(selector labels.Selector) ([]*v1alpha1.Application, error) {
115+
res, err := f.clientset.ArgoprojV1alpha1().Applications(f.namespace).List(context.Background(), metav1.ListOptions{
116+
LabelSelector: selector.String(),
117+
})
118+
if err != nil {
119+
return nil, err
120+
}
121+
var apps []*v1alpha1.Application
122+
for i := range res.Items {
123+
apps = append(apps, &res.Items[i])
124+
}
125+
return apps, nil
126+
}
127+
101128
func newMockHandler(reactor *reactorDef, applicationNamespaces []string, maxPayloadSize int64, argoDB db.ArgoDB, argoSettings *settings.ArgoCDSettings, objects ...runtime.Object) *ArgoCDWebhookHandler {
102129
appClientset := appclientset.NewSimpleClientset(objects...)
103130
if reactor != nil {
@@ -109,8 +136,7 @@ func newMockHandler(reactor *reactorDef, applicationNamespaces []string, maxPayl
109136
appClientset.AddReactor(reactor.verb, reactor.resource, reactor.reaction)
110137
}
111138
cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour))
112-
113-
return NewHandler("argocd", applicationNamespaces, 10, appClientset, argoSettings, &fakeSettingsSrc{}, cache.NewCache(
139+
return NewHandler("argocd", applicationNamespaces, 10, appClientset, &fakeAppsLister{clientset: appClientset}, argoSettings, &fakeSettingsSrc{}, cache.NewCache(
114140
cacheClient,
115141
1*time.Minute,
116142
1*time.Minute,

0 commit comments

Comments
 (0)