@@ -34,7 +34,6 @@ type actionRepo struct {
3434 // Subscriber management for LISTEN/NOTIFY
3535 runSubscribers map [chan string ]bool
3636 actionSubscribers map [chan string ]bool
37- abortSubscribers map [chan string ]bool
3837 mu sync.RWMutex
3938}
4039
@@ -50,7 +49,6 @@ func NewActionRepo(db *gorm.DB, dbConfig database.DbConfig) interfaces.ActionRep
5049 pgConfig : dbConfig .Postgres ,
5150 runSubscribers : make (map [chan string ]bool ),
5251 actionSubscribers : make (map [chan string ]bool ),
53- abortSubscribers : make (map [chan string ]bool ),
5452 }
5553
5654 // Start LISTEN/NOTIFY for PostgreSQL
@@ -274,9 +272,8 @@ func (r *actionRepo) AbortRun(ctx context.Context, runID *common.RunIdentifier,
274272 return fmt .Errorf ("failed to abort run: %w" , result .Error )
275273 }
276274
277- // Notify run subscribers and abort reconciler .
275+ // Notify run subscribers.
278276 r .notifyRunUpdate (ctx , runID )
279- r .notifyAbortRequest (ctx , & common.ActionIdentifier {Run : runID , Name : runID .Name })
280277
281278 logger .Infof (ctx , "Aborted run: %s/%s/%s/%s" , runID .Org , runID .Project , runID .Domain , runID .Name )
282279 return nil
@@ -476,17 +473,16 @@ func (r *actionRepo) AbortAction(ctx context.Context, actionID *common.ActionIde
476473
477474 result := r .db .WithContext (ctx ).
478475 Model (& models.Action {}).
479- Where ("org = ? AND project = ? AND domain = ? AND name = ?" ,
480- actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Name ).
476+ Where ("org = ? AND project = ? AND domain = ? AND run_name = ? AND name = ?" ,
477+ actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Run . Name , actionID . Name ).
481478 Updates (updates )
482479
483480 if result .Error != nil {
484481 return fmt .Errorf ("failed to abort action: %w" , result .Error )
485482 }
486483
487- // Notify action subscribers and abort reconciler .
484+ // Notify action subscribers.
488485 r .notifyActionUpdate (ctx , actionID )
489- r .notifyAbortRequest (ctx , actionID )
490486
491487 logger .Infof (ctx , "Aborted action: %s" , actionID .Name )
492488 return nil
@@ -509,8 +505,8 @@ func (r *actionRepo) ListPendingAborts(ctx context.Context) ([]*models.Action, e
509505func (r * actionRepo ) MarkAbortAttempt (ctx context.Context , actionID * common.ActionIdentifier ) (int , error ) {
510506 result := r .db .WithContext (ctx ).
511507 Model (& models.Action {}).
512- Where ("org = ? AND project = ? AND domain = ? AND name = ?" ,
513- actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Name ).
508+ Where ("org = ? AND project = ? AND domain = ? AND run_name = ? AND name = ?" ,
509+ actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Run . Name , actionID . Name ).
514510 Updates (map [string ]interface {}{
515511 "abort_attempt_count" : gorm .Expr ("abort_attempt_count + 1" ),
516512 "updated_at" : time .Now (),
@@ -523,8 +519,8 @@ func (r *actionRepo) MarkAbortAttempt(ctx context.Context, actionID *common.Acti
523519 var action models.Action
524520 if err := r .db .WithContext (ctx ).
525521 Select ("abort_attempt_count" ).
526- Where ("org = ? AND project = ? AND domain = ? AND name = ?" ,
527- actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Name ).
522+ Where ("org = ? AND project = ? AND domain = ? AND run_name = ? AND name = ?" ,
523+ actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Run . Name , actionID . Name ).
528524 First (& action ).Error ; err != nil {
529525 return 0 , fmt .Errorf ("failed to read abort attempt count: %w" , err )
530526 }
@@ -535,8 +531,8 @@ func (r *actionRepo) MarkAbortAttempt(ctx context.Context, actionID *common.Acti
535531func (r * actionRepo ) ClearAbortRequest (ctx context.Context , actionID * common.ActionIdentifier ) error {
536532 result := r .db .WithContext (ctx ).
537533 Model (& models.Action {}).
538- Where ("org = ? AND project = ? AND domain = ? AND name = ?" ,
539- actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Name ).
534+ Where ("org = ? AND project = ? AND domain = ? AND run_name = ? AND name = ?" ,
535+ actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Run . Name , actionID . Name ).
540536 Updates (map [string ]interface {}{
541537 "abort_requested_at" : nil ,
542538 "abort_attempt_count" : 0 ,
@@ -549,78 +545,6 @@ func (r *actionRepo) ClearAbortRequest(ctx context.Context, actionID *common.Act
549545 return nil
550546}
551547
552- // WatchAbortRequests delivers abort_requests NOTIFY payloads to the caller.
553- // On non-Postgres setups it polls for pending aborts every 5 seconds.
554- func (r * actionRepo ) WatchAbortRequests (ctx context.Context , payloads chan <- string , errs chan <- error ) {
555- if r .isPostgres {
556- notifCh := make (chan string , 20 )
557-
558- r .mu .Lock ()
559- r .abortSubscribers [notifCh ] = true
560- r .mu .Unlock ()
561-
562- defer func () {
563- r .mu .Lock ()
564- delete (r .abortSubscribers , notifCh )
565- close (notifCh )
566- r .mu .Unlock ()
567- }()
568-
569- for {
570- select {
571- case <- ctx .Done ():
572- return
573- case payload := <- notifCh :
574- select {
575- case payloads <- payload :
576- case <- ctx .Done ():
577- return
578- }
579- }
580- }
581- } else {
582- // SQLite fallback: poll for pending aborts periodically.
583- ticker := time .NewTicker (5 * time .Second )
584- defer ticker .Stop ()
585- for {
586- select {
587- case <- ctx .Done ():
588- return
589- case <- ticker .C :
590- actions , err := r .ListPendingAborts (ctx )
591- if err != nil {
592- select {
593- case errs <- err :
594- default :
595- }
596- continue
597- }
598- for _ , a := range actions {
599- payload := fmt .Sprintf ("%s/%s/%s/%s/%s" , a .Org , a .Project , a .Domain , a .RunName , a .Name )
600- select {
601- case payloads <- payload :
602- case <- ctx .Done ():
603- return
604- }
605- }
606- }
607- }
608- }
609- }
610-
611- // notifyAbortRequest fires NOTIFY abort_requests so the AbortReconciler wakes immediately.
612- func (r * actionRepo ) notifyAbortRequest (ctx context.Context , actionID * common.ActionIdentifier ) {
613- if ! r .isPostgres {
614- return
615- }
616- payload := fmt .Sprintf ("%s/%s/%s/%s/%s" ,
617- actionID .Run .Org , actionID .Run .Project , actionID .Run .Domain , actionID .Run .Name , actionID .Name )
618- notifySQL := fmt .Sprintf ("NOTIFY abort_requests, '%s'" , payload )
619- if err := r .db .WithContext (ctx ).Exec (notifySQL ).Error ; err != nil {
620- logger .Errorf (ctx , "Failed to NOTIFY abort_requests: %v" , err )
621- }
622- }
623-
624548// UpdateActionState updates the state of an action
625549func (r * actionRepo ) UpdateActionState (ctx context.Context , actionID * common.ActionIdentifier , state string ) error {
626550 // Parse the state JSON to extract the phase
@@ -953,11 +877,6 @@ func (r *actionRepo) startPostgresListener() {
953877 return
954878 }
955879
956- if err := r .listener .Listen ("abort_requests" ); err != nil {
957- logger .Errorf (context .Background (), "Failed to listen to abort_requests: %v" , err )
958- return
959- }
960-
961880 logger .Infof (context .Background (), "PostgreSQL LISTEN/NOTIFY started" )
962881
963882 // Process notifications
@@ -994,17 +913,6 @@ func (r *actionRepo) startPostgresListener() {
994913 }
995914 r .mu .RUnlock ()
996915
997- case "abort_requests" :
998- // Broadcast to all abort reconciler subscribers
999- r .mu .RLock ()
1000- for ch := range r .abortSubscribers {
1001- select {
1002- case ch <- notif .Extra :
1003- default :
1004- logger .Warnf (context .Background (), "Abort subscriber channel full, dropping notification" )
1005- }
1006- }
1007- r .mu .RUnlock ()
1008916 }
1009917
1010918 case <- time .After (90 * time .Second ):
0 commit comments