@@ -19,11 +19,13 @@ package controller
1919import (
2020 "context"
2121 "errors"
22+ "fmt"
2223 "strconv"
2324 "time"
2425
2526 batchv1 "k8s.io/api/batch/v1"
2627 v1 "k8s.io/api/core/v1"
28+ "k8s.io/apimachinery/pkg/api/meta"
2729 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2830 "k8s.io/apimachinery/pkg/runtime"
2931 "k8s.io/apimachinery/pkg/types"
@@ -47,6 +49,7 @@ type AppWrapperReconciler struct {
4749 Events chan event.GenericEvent // event channel to trigger dispatch
4850 ClusterCapacity Weights // cluster capacity available to MCAD
4951 NextSync time.Time // when to refresh cluster capacity
52+ Decisions map [types.UID ]* QueuingDecision // transient log of queuing decisions to enable recording in AppWrapper Status
5053}
5154
5255const (
@@ -124,6 +127,7 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request)
124127 }
125128 // remove AppWrapper from cache
126129 r .deleteCachedAW (appWrapper )
130+ delete (r .Decisions , appWrapper .UID )
127131 log .FromContext (ctx ).Info ("Deleted" )
128132 return ctrl.Result {}, nil
129133 }
@@ -141,8 +145,27 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request)
141145 return r .updateStatus (ctx , appWrapper , mcadv1beta1 .Queued , mcadv1beta1 .Idle )
142146
143147 case mcadv1beta1 .Queued :
144- r .triggerDispatch ()
145- return ctrl.Result {}, nil
148+ // Propagate most recent queuing decision to AppWrapper's Queued Condition
149+ if decision , ok := r .Decisions [appWrapper .UID ]; ok {
150+ meta .SetStatusCondition (& appWrapper .Status .Conditions , metav1.Condition {
151+ Type : string (mcadv1beta1 .Queued ),
152+ Status : metav1 .ConditionTrue ,
153+ Reason : string (decision .reason ),
154+ Message : decision .message ,
155+ })
156+ if r .Status ().Update (ctx , appWrapper ) == nil {
157+ // If successfully propagated, remove from in memory map
158+ delete (r .Decisions , appWrapper .UID )
159+ }
160+ }
161+
162+ if meta .FindStatusCondition (appWrapper .Status .Conditions , string (mcadv1beta1 .Queued )) == nil {
163+ // Absence of Queued Condition strongly suggests AppWrapper is new; trigger dispatch and a short requeue
164+ r .triggerDispatch ()
165+ return ctrl.Result {RequeueAfter : deletionDelay }, nil
166+ } else {
167+ return ctrl.Result {RequeueAfter : queuedDelay }, nil
168+ }
146169
147170 case mcadv1beta1 .Running :
148171 switch appWrapper .Status .Step {
@@ -193,7 +216,21 @@ func (r *AppWrapperReconciler) Reconcile(ctx context.Context, req ctrl.Request)
193216 // reset status to queued/idle
194217 appWrapper .Status .Restarts += 1
195218 appWrapper .Status .RequeueTimestamp = metav1 .Now () // overwrite requeue decision time with completion time
196- return r .updateStatus (ctx , appWrapper , mcadv1beta1 .Queued , mcadv1beta1 .Idle )
219+ msg := "Requeued by MCAD"
220+ if decision , ok := r .Decisions [appWrapper .UID ]; ok && decision .reason == mcadv1beta1 .QueuedRequeue {
221+ msg = fmt .Sprintf ("Requeued because %s" , decision .message )
222+ }
223+ meta .SetStatusCondition (& appWrapper .Status .Conditions , metav1.Condition {
224+ Type : string (mcadv1beta1 .Queued ),
225+ Status : metav1 .ConditionTrue ,
226+ Reason : string (mcadv1beta1 .QueuedRequeue ),
227+ Message : msg ,
228+ })
229+ res , err := r .updateStatus (ctx , appWrapper , mcadv1beta1 .Queued , mcadv1beta1 .Idle )
230+ if err == nil {
231+ delete (r .Decisions , appWrapper .UID )
232+ }
233+ return res , err
197234 }
198235
199236 case mcadv1beta1 .Failed :
@@ -295,6 +332,7 @@ func (r *AppWrapperReconciler) requeueOrFail(ctx context.Context, appWrapper *mc
295332 }
296333 // requeue AppWrapper
297334 appWrapper .Status .RequeueTimestamp = metav1 .Now ()
335+ r .Decisions [appWrapper .UID ] = & QueuingDecision {reason : mcadv1beta1 .QueuedRequeue , message : reason }
298336 return r .updateStatus (ctx , appWrapper , mcadv1beta1 .Running , mcadv1beta1 .Deleting , reason )
299337}
300338
@@ -332,6 +370,12 @@ func (r *AppWrapperReconciler) dispatch(ctx context.Context) (ctrl.Result, error
332370 }
333371 // set dispatching time and status
334372 appWrapper .Status .DispatchTimestamp = metav1 .Now ()
373+ meta .SetStatusCondition (& appWrapper .Status .Conditions , metav1.Condition {
374+ Type : string (mcadv1beta1 .Queued ),
375+ Status : metav1 .ConditionFalse ,
376+ Reason : string (mcadv1beta1 .QueuedDispatch ),
377+ Message : "Selected for dispatch" ,
378+ })
335379 if _ , err := r .updateStatus (ctx , appWrapper , mcadv1beta1 .Running , mcadv1beta1 .Creating ); err != nil {
336380 return ctrl.Result {}, err
337381 }
0 commit comments