@@ -30,17 +30,23 @@ type _change_operation = {
3030 object : KubernetesObject ;
3131} ;
3232
33- const PENDING_CHANGES : _change_operation [ ] = [ ] ;
33+ const PENDING_CHANGES = new Map < string , _change_operation > ( ) ;
34+
35+ function getObjectKey ( object : KubernetesObject ) : string {
36+ // it is suprising that sometimes the uid is not unique, so we need to check the apiVersion and kind as well
37+ return `${ object . apiVersion } /${ object . kind } :${ object . metadata . uid } ` ;
38+ }
3439
3540export function handleEvent ( event : KuviewEvent ) {
41+ const key = getObjectKey ( event . object ) ;
3642 switch ( event . type ) {
3743 case "create" :
3844 case "update" :
3945 case "generic" :
40- PENDING_CHANGES . push ( { type : "UPSERT" , object : event . object } ) ;
46+ PENDING_CHANGES . set ( key , { type : "UPSERT" , object : event . object } ) ;
4147 break ;
4248 case "delete" :
43- PENDING_CHANGES . push ( { type : "DELETE" , object : event . object } ) ;
49+ PENDING_CHANGES . set ( key , { type : "DELETE" , object : event . object } ) ;
4450 break ;
4551 }
4652}
@@ -51,13 +57,21 @@ export function useGVKSyncHook(gvk: string) {
5157 const [ objects , setObjects ] = useAtom ( objectAtom ) ;
5258
5359 const sync = ( ) => {
54- const operations = PENDING_CHANGES . filter (
55- ( operation ) =>
56- `${ operation . object . apiVersion } /${ operation . object . kind } ` === gvk ,
57- ) ;
58- if ( operations . length == 0 ) return ;
60+ const operations : _change_operation [ ] = [ ] ;
61+ PENDING_CHANGES . forEach ( ( op , key ) => {
62+ if ( `${ op . object . apiVersion } /${ op . object . kind } ` === gvk ) {
63+ operations . push ( op ) ;
64+ PENDING_CHANGES . delete ( key ) ;
65+ }
66+ } ) ;
67+
68+ if ( operations . length === 0 ) return ;
69+
70+ const newObjects = { ...objects } ;
71+ let updated = false ;
5972
6073 operations . forEach ( ( operation ) => {
74+ updated = true ;
6175 const { type, object } = operation ;
6276 const { metadata } = object ;
6377 const nn = metadata . namespace
@@ -68,28 +82,17 @@ export function useGVKSyncHook(gvk: string) {
6882
6983 switch ( type ) {
7084 case "UPSERT" :
71- objects [ nn ] = object ;
85+ newObjects [ nn ] = object ;
7286 break ;
7387 case "DELETE" :
74- delete objects [ nn ] ;
88+ delete newObjects [ nn ] ;
7589 break ;
7690 }
7791 } ) ;
7892
79- for ( const operation of operations ) {
80- const index = PENDING_CHANGES . findIndex (
81- ( o ) =>
82- // it is suprising that sometimes the uid is not unique, so we need to check the apiVersion and kind as well
83- `${ o . object . apiVersion } /${ o . object . kind } ` ===
84- `${ operation . object . apiVersion } /${ operation . object . kind } ` &&
85- o . object . metadata . uid === operation . object . metadata . uid ,
86- ) ;
87- if ( index !== - 1 ) {
88- PENDING_CHANGES . splice ( index , 1 ) ;
89- }
93+ if ( updated ) {
94+ setObjects ( newObjects ) ;
9095 }
91-
92- setObjects ( { ...objects } ) ;
9396 } ;
9497
9598 useEffect ( ( ) => {
@@ -104,7 +107,7 @@ export function useKubernetesAtomSyncHook() {
104107 const [ kubernetes , setKubernetes ] = useAtom ( kubernetesAtom ) ;
105108 useEffect ( ( ) => {
106109 const interval = setInterval ( ( ) => {
107- for ( const operation of PENDING_CHANGES ) {
110+ for ( const operation of PENDING_CHANGES . values ( ) ) {
108111 const { object } = operation ;
109112 const { kind, apiVersion } = object ;
110113 const gvk = `${ apiVersion } /${ kind } ` ;
@@ -135,12 +138,15 @@ export function useServiceEndpointSliceSyncHook() {
135138 const [ endpointSlices , setEndpointSlices ] = useAtom ( endpointSliceAtom ) ;
136139
137140 const sync = ( ) => {
138- // 1. find all operations that are related to services and endpoint slices
139- const operations = PENDING_CHANGES . filter (
140- ( operation ) =>
141- operation . object . kind === "Service" ||
142- operation . object . kind === "EndpointSlice" ,
143- ) ;
141+ const operations : _change_operation [ ] = [ ] ;
142+ PENDING_CHANGES . forEach ( ( op , key ) => {
143+ if ( op . object . kind === "Service" || op . object . kind === "EndpointSlice" ) {
144+ operations . push ( op ) ;
145+ PENDING_CHANGES . delete ( key ) ;
146+ }
147+ } ) ;
148+
149+ if ( operations . length === 0 ) return ;
144150
145151 // 2. update services first
146152 const serviceOperations = operations . filter (
@@ -218,14 +224,6 @@ export function useServiceEndpointSliceSyncHook() {
218224 }
219225 }
220226
221- // 6. remove operations from PENDING_CHANGES
222- for ( const operation of operations ) {
223- const index = PENDING_CHANGES . findIndex (
224- ( o ) => o . object . metadata . uid === operation . object . metadata . uid ,
225- ) ;
226- if ( index !== - 1 ) PENDING_CHANGES . splice ( index , 1 ) ;
227- }
228-
229227 setServices ( { ...services } ) ;
230228 setEndpointSlices ( { ...endpointSlices } ) ;
231229 } ;
0 commit comments