11using GithubActionsOrchestrator . Database ;
2+ using GithubActionsOrchestrator . Models ;
23using Microsoft . AspNetCore . Mvc ;
34using Microsoft . EntityFrameworkCore ;
45using Npgsql . Internal ;
@@ -7,6 +8,12 @@ namespace GithubActionsOrchestrator;
78[ Route ( "/api" ) ]
89public class ApiController : Controller
910{
11+ private readonly RunnerQueue _runnerQueue ;
12+
13+ public ApiController ( RunnerQueue runnerQueue )
14+ {
15+ _runnerQueue = runnerQueue ;
16+ }
1017 [ Route ( "get-runners" ) ]
1118 public async Task < IResult > GetRunners ( [ FromQuery ] int limit = 100 , [ FromQuery ] int offset = 0 )
1219 {
@@ -85,5 +92,46 @@ public async Task<IResult> GetProvisionScript(string provisionId,[FromHeader(Nam
8592
8693 }
8794
95+ [ Route ( "kill-non-processing-runners" ) ]
96+ [ HttpPost ]
97+ public async Task < IResult > KillNonProcessingRunners ( )
98+ {
99+ var db = new ActionsRunnerContext ( ) ;
100+
101+ // Find all runners that are not in Processing state using the lifecycle table
102+ var runnersToKill = await db . Runners
103+ . AsNoTracking ( )
104+ . Where ( r => db . RunnerLifecycles
105+ . Where ( rl => rl . RunnerId == r . RunnerId )
106+ . OrderByDescending ( rl => rl . EventTimeUtc )
107+ . First ( ) . Status != RunnerStatus . Processing &&
108+ db . RunnerLifecycles
109+ . Where ( rl => rl . RunnerId == r . RunnerId )
110+ . OrderByDescending ( rl => rl . EventTimeUtc )
111+ . First ( ) . Status != RunnerStatus . DeletionQueued &&
112+ db . RunnerLifecycles
113+ . Where ( rl => rl . RunnerId == r . RunnerId )
114+ . OrderByDescending ( rl => rl . EventTimeUtc )
115+ . First ( ) . Status != RunnerStatus . Deleted )
116+ . Select ( r => new { r . RunnerId , r . CloudServerId , r . Hostname } )
117+ . ToListAsync ( ) ;
118+
119+ // Queue deletion for each runner
120+ foreach ( var runner in runnersToKill )
121+ {
122+ _runnerQueue . DeleteTasks . Enqueue ( new DeleteRunnerTask
123+ {
124+ ServerId = runner . CloudServerId ,
125+ RunnerDbId = runner . RunnerId
126+ } ) ;
127+ }
128+
129+ return Results . Json ( new
130+ {
131+ message = $ "Queued { runnersToKill . Count } runners for deletion",
132+ killedRunners = runnersToKill . Select ( r => new { r . RunnerId , r . Hostname } ) . ToList ( )
133+ } ) ;
134+ }
135+
88136
89137}
0 commit comments