@@ -8,13 +8,17 @@ import (
8
8
"context"
9
9
"os"
10
10
11
+ "github.com/google/go-cmp/cmp"
12
+ "github.com/google/go-cmp/cmp/cmpopts"
11
13
"k8s.io/apimachinery/pkg/api/errors"
12
14
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
15
ctrl "sigs.k8s.io/controller-runtime"
14
16
"sigs.k8s.io/controller-runtime/pkg/client"
15
17
"sigs.k8s.io/controller-runtime/pkg/controller"
18
+ "sigs.k8s.io/controller-runtime/pkg/event"
16
19
"sigs.k8s.io/controller-runtime/pkg/handler"
17
20
"sigs.k8s.io/controller-runtime/pkg/log"
21
+ "sigs.k8s.io/controller-runtime/pkg/predicate"
18
22
"sigs.k8s.io/controller-runtime/pkg/source"
19
23
20
24
config "github.com/gitpod-io/gitpod/ws-manager/api/config"
@@ -76,5 +80,24 @@ func (r *SubscriberReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
76
80
}
77
81
}()
78
82
79
- return c .Watch (source .Kind (mgr .GetCache (), & workspacev1.Workspace {}), & handler.EnqueueRequestForObject {})
83
+ // we need several reconciliation loops during a workspace creation until it reaches a stable state.
84
+ // this introduces the side effect of multiple notifications to the subscribers with partial information.
85
+ // the filterByUpdate predicate acts as a filter to avoid this
86
+ filterByUpdate := predicate.Funcs {
87
+ CreateFunc : func (ce event.CreateEvent ) bool {
88
+ return true
89
+ },
90
+ UpdateFunc : func (e event.UpdateEvent ) bool {
91
+ old := e .ObjectOld .(* workspacev1.Workspace )
92
+ new := e .ObjectNew .(* workspacev1.Workspace )
93
+
94
+ if ! cmp .Equal (old .Spec .Ports , new .Spec .Ports ) {
95
+ return true
96
+ }
97
+
98
+ return ! cmp .Equal (old .Status , new .Status , cmpopts .IgnoreFields (workspacev1.WorkspaceStatus {}, "LastActivity" ))
99
+ },
100
+ }
101
+
102
+ return c .Watch (source .Kind (mgr .GetCache (), & workspacev1.Workspace {}), & handler.EnqueueRequestForObject {}, filterByUpdate )
80
103
}
0 commit comments