@@ -23,11 +23,27 @@ import (
2323 "github.com/nephio-project/porch/pkg/repository"
2424 "go.opentelemetry.io/otel/trace"
2525 metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
26+ "k8s.io/apimachinery/pkg/runtime"
2627 "k8s.io/apimachinery/pkg/watch"
2728 genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
2829 "k8s.io/klog/v2"
2930)
3031
32+ // createGenericWatch creates a watch.Interface that monitors package changes.
33+ func createGenericWatch (ctx context.Context , r packageReader , filter repository.ListPackageRevisionFilter , extractor objectExtractor ) (watch.Interface , error ) {
34+ ctx , cancel := context .WithCancel (ctx )
35+
36+ w := & watcher {
37+ cancel : cancel ,
38+ resultChan : make (chan watch.Event , 64 ),
39+ extractor : extractor ,
40+ }
41+
42+ go w .listAndWatch (ctx , r , filter )
43+
44+ return w , nil
45+ }
46+
3147// Watch supports watching for changes.
3248func (r * packageRevisions ) Watch (ctx context.Context , options * metainternalversion.ListOptions ) (watch.Interface , error ) {
3349 // 'label' selects on labels; 'field' selects on the object's fields. Not all fields
@@ -49,16 +65,9 @@ func (r *packageRevisions) Watch(ctx context.Context, options *metainternalversi
4965 }
5066 }
5167
52- ctx , cancel := context .WithCancel (ctx )
53-
54- w := & watcher {
55- cancel : cancel ,
56- resultChan : make (chan watch.Event , 64 ),
57- }
58-
59- go w .listAndWatch (ctx , r , * filter )
60-
61- return w , nil
68+ return createGenericWatch (ctx , r , * filter , func (ctx context.Context , pr repository.PackageRevision ) (runtime.Object , error ) {
69+ return pr .GetPackageRevision (ctx )
70+ })
6271}
6372
6473// watcher implements watch.Interface, and holds the state for an active watch.
@@ -72,6 +81,9 @@ type watcher struct {
7281 eventCallback func (eventType watch.EventType , pr repository.PackageRevision ) bool
7382 done bool
7483 totalSent int
84+
85+ // objectExtractor function to get the appropriate object from PackageRevision
86+ extractor objectExtractor
7587}
7688
7789var _ watch.Interface = & watcher {}
@@ -94,10 +106,20 @@ type packageReader interface {
94106 listPackageRevisions (ctx context.Context , filter repository.ListPackageRevisionFilter , callback func (ctx context.Context , p repository.PackageRevision ) error ) error
95107}
96108
109+ // objectExtractor transforms a repository.PackageRevision into the appropriate
110+ // resource (PackageRevision or PackageRevisionResources).
111+ type objectExtractor func (ctx context.Context , pr repository.PackageRevision ) (runtime.Object , error )
112+
97113// listAndWatch implements watch by doing a list, then sending any observed changes.
98114// This is not a compliant implementation of watch, but it is a good-enough start for most controllers.
99115// One trick is that we start the watch _before_ we perform the list, so we don't miss changes that happen immediately after the list.
100116func (w * watcher ) listAndWatch (ctx context.Context , r packageReader , filter repository.ListPackageRevisionFilter ) {
117+ if w .extractor == nil {
118+ w .extractor = func (ctx context.Context , pr repository.PackageRevision ) (runtime.Object , error ) {
119+ return pr .GetPackageRevision (ctx )
120+ }
121+ }
122+
101123 if err := w .listAndWatchInner (ctx , r , filter ); err != nil {
102124 // TODO: We need to populate the object on this error
103125 klog .Warningf ("sending error to watch stream: %v" , err )
@@ -121,7 +143,7 @@ func (w *watcher) listAndWatchInner(ctx context.Context, r packageReader, filter
121143 if w .done {
122144 return false
123145 }
124- obj , err := pr . GetPackageRevision (ctx )
146+ obj , err := w . extractor (ctx , pr )
125147 if err != nil {
126148 w .done = true
127149 errorResult <- err
@@ -144,7 +166,7 @@ func (w *watcher) listAndWatchInner(ctx context.Context, r packageReader, filter
144166 sentAdd := 0
145167 // TODO: Only if rv == 0?
146168 if err := r .listPackageRevisions (ctx , filter , func (ctx context.Context , p repository.PackageRevision ) error {
147- obj , err := p . GetPackageRevision (ctx )
169+ obj , err := w . extractor (ctx , p )
148170 if err != nil {
149171 w .mutex .Lock ()
150172 w .done = true
@@ -200,7 +222,7 @@ func (w *watcher) listAndWatchInner(ctx context.Context, r packageReader, filter
200222 if w .done {
201223 return false
202224 }
203- obj , err := pr . GetPackageRevision (ctx )
225+ obj , err := w . extractor (ctx , pr )
204226 if err != nil {
205227 w .done = true
206228 errorResult <- err
0 commit comments