@@ -24,22 +24,30 @@ public function __construct()
2424 $ this
2525 ->desc ('Schedules tasks on regular intervals by publishing them to our queues ' )
2626 ->inject ('dbForPlatform ' )
27+ ->inject ('getProjectDB ' )
2728 ->inject ('queueForCertificates ' )
2829 ->callback ($ this ->action (...));
2930 }
3031
31- public function action (Database $ dbForPlatform , Certificate $ queueForCertificates ): void
32+ public function action (Database $ dbForPlatform , callable $ getProjectDB , Certificate $ queueForCertificates ): void
3233 {
3334 Console::title ('Interval V1 ' );
3435 Console::success (APP_NAME . ' interval process v1 has started ' );
3536
3637 $ intervalDomainVerification = (int ) System::getEnv ('_APP_INTERVAL_DOMAIN_VERIFICATION ' , '60 ' ); // 1 minute
38+ $ intervalCleanupStaleExecutions = (int ) System::getEnv ('_APP_INTERVAL_CLEANUP_STALE_EXECUTIONS ' , '300 ' ); // 5 minutes
3739
3840 \go (function () use ($ dbForPlatform , $ queueForCertificates , $ intervalDomainVerification ) {
3941 Console::loop (function () use ($ dbForPlatform , $ queueForCertificates ) {
4042 $ this ->verifyDomain ($ dbForPlatform , $ queueForCertificates );
4143 }, $ intervalDomainVerification );
4244 });
45+
46+ \go (function () use ($ dbForPlatform , $ getProjectDB , $ intervalCleanupStaleExecutions ) {
47+ Console::loop (function () use ($ dbForPlatform , $ getProjectDB ) {
48+ $ this ->cleanupStaleExecutions ($ dbForPlatform , $ getProjectDB );
49+ }, $ intervalCleanupStaleExecutions );
50+ });
4351 }
4452
4553 private function verifyDomain (Database $ dbForPlatform , Certificate $ queueForCertificates ): void
@@ -72,4 +80,47 @@ private function verifyDomain(Database $dbForPlatform, Certificate $queueForCert
7280 ->trigger ();
7381 }
7482 }
83+
84+ private function cleanupStaleExecutions (Database $ dbForPlatform , callable $ getProjectDB ): void
85+ {
86+ $ time = DatabaseDateTime::now ();
87+ $ staleThreshold = DatabaseDateTime::addSeconds (new DateTime (), -1800 ); // 30 minutes ago
88+
89+ Console::info ("[ {$ time }] Starting cleanup of stale executions " );
90+
91+ $ dbForPlatform ->foreach (
92+ 'projects ' ,
93+ function (Document $ project ) use ($ getProjectDB , $ time , $ staleThreshold ) {
94+ try {
95+ $ dbForProject = $ getProjectDB ($ project );
96+
97+ $ staleExecutions = $ dbForProject ->find ('executions ' , [
98+ Query::equal ('status ' , ['processing ' ]),
99+ Query::lessThan ('$createdAt ' , $ staleThreshold ),
100+ Query::limit (100 ),
101+ ]);
102+
103+ if (\count ($ staleExecutions ) === 0 ) {
104+ return ;
105+ }
106+
107+ Console::info ("[ {$ time }] Found " . \count ($ staleExecutions ) . " stale executions in project {$ project ->getId ()}" );
108+
109+ foreach ($ staleExecutions as $ execution ) {
110+ $ execution ->setAttribute ('status ' , 'failed ' );
111+ $ execution ->setAttribute ('errors ' , 'Execution timed out ' );
112+ $ dbForProject ->updateDocument ('executions ' , $ execution ->getId (), $ execution );
113+ }
114+ } catch (\Throwable $ th ) {
115+ Console::error ("[ {$ time }] Failed to cleanup stale executions for project {$ project ->getId ()}: " . $ th ->getMessage ());
116+ }
117+ },
118+ [
119+ Query::equal ('region ' , [System::getEnv ('_APP_REGION ' , 'default ' )]),
120+ Query::limit (100 ),
121+ ]
122+ );
123+
124+ Console::info ("[ {$ time }] Completed cleanup of stale executions " );
125+ }
75126}
0 commit comments