@@ -79,6 +79,11 @@ type recentCompletions struct {
7979 mutex gosync.RWMutex
8080}
8181
82+ type lastSeenVersions struct {
83+ versions map [string ]string
84+ mutex gosync.RWMutex
85+ }
86+
8287// WorkflowController is the controller for workflow resources
8388type WorkflowController struct {
8489 // namespace of the workflow controller
@@ -148,6 +153,8 @@ type WorkflowController struct {
148153 executorPlugins map [string ]map [string ]* spec.Plugin // namespace -> name -> plugin
149154
150155 recentCompletions recentCompletions
156+
157+ lastSeenVersions lastSeenVersions // key: workflow UID, value: resource version
151158}
152159
153160const (
@@ -201,6 +208,10 @@ func NewWorkflowController(ctx context.Context, restConfig *rest.Config, kubecli
201208 eventRecorderManager : events .NewEventRecorderManager (kubeclientset ),
202209 progressPatchTickDuration : env .LookupEnvDurationOr (common .EnvVarProgressPatchTickDuration , 1 * time .Minute ),
203210 progressFileTickDuration : env .LookupEnvDurationOr (common .EnvVarProgressFileTickDuration , 3 * time .Second ),
211+ lastSeenVersions : lastSeenVersions {
212+ versions : make (map [string ]string ),
213+ mutex : gosync.RWMutex {},
214+ },
204215 }
205216
206217 if executorPlugins {
@@ -687,6 +698,12 @@ func (wfc *WorkflowController) processNextItem(ctx context.Context) bool {
687698 return true
688699 }
689700
701+ if wfc .isOutdated (un ) {
702+ log .WithField ("key" , key ).Debug ("Skipping outdated workflow event" )
703+ wfc .wfQueue .AddRateLimited (key )
704+ return true
705+ }
706+
690707 if ! reconciliationNeeded (un ) {
691708 log .WithFields (log.Fields {"key" : key }).Debug ("Won't process Workflow since it's completed" )
692709 return true
@@ -903,6 +920,7 @@ func (wfc *WorkflowController) addWorkflowInformerHandlers(ctx context.Context)
903920 if ! needed {
904921 key , _ := cache .MetaNamespaceKeyFunc (un )
905922 wfc .recordCompletedWorkflow (key )
923+ wfc .deleteLastSeenVersionKey (wfc .getLastSeenVersionKey (un ))
906924 }
907925 return needed
908926 },
@@ -960,6 +978,7 @@ func (wfc *WorkflowController) addWorkflowInformerHandlers(ctx context.Context)
960978 // no need to add to the queue - this workflow is done
961979 wfc .throttler .Remove (key )
962980 }
981+ wfc .deleteLastSeenVersionKey (wfc .getLastSeenVersionKey (obj .(* unstructured.Unstructured )))
963982 },
964983 },
965984 },
@@ -1300,3 +1319,25 @@ func (wfc *WorkflowController) IsLeader() bool {
13001319 // the wfc.wfInformer is nil if it is not the leader
13011320 return wfc .wfInformer != nil
13021321}
1322+
1323+ func (wfc * WorkflowController ) isOutdated (wf metav1.Object ) bool {
1324+ wfc .lastSeenVersions .mutex .RLock ()
1325+ defer wfc .lastSeenVersions .mutex .RUnlock ()
1326+ lastSeenRV , ok := wfc .lastSeenVersions .versions [wfc .getLastSeenVersionKey (wf )]
1327+ // always process if not seen before
1328+ if ! ok || lastSeenRV == "" {
1329+ return false
1330+ }
1331+ annotations := wf .GetAnnotations ()[common .AnnotationKeyLastSeenVersion ]
1332+ return annotations != lastSeenRV
1333+ }
1334+
1335+ func (wfc * WorkflowController ) getLastSeenVersionKey (wf metav1.Object ) string {
1336+ return string (wf .GetUID ())
1337+ }
1338+
1339+ func (wfc * WorkflowController ) deleteLastSeenVersionKey (key string ) {
1340+ wfc .lastSeenVersions .mutex .Lock ()
1341+ defer wfc .lastSeenVersions .mutex .Unlock ()
1342+ delete (wfc .lastSeenVersions .versions , key )
1343+ }
0 commit comments