@@ -94,7 +94,11 @@ public function create(): void
9494 throw new \RuntimeException ('Database is not ready for feature ' . $ this ->getFeatureName () . ' after waiting period. ' );
9595 }
9696
97- $ database = $ this ->getDatabase ($ responseBody ->getId ());
97+ $ database = $ this ->getDatabase (
98+ $ responseBody ->getId (),
99+ (int ) get ('mittwald_database_wait ' , 30 ),
100+ (int ) get ('mittwald_database_retries ' , 20 ),
101+ );
98102
99103 $ reachable = $ this ->checkDatabaseHostReachable (
100104 $ database ->getHostName (),
@@ -114,7 +118,11 @@ public function create(): void
114118 // dependency for db_sync_tool, TYPO3 CLI, and all subsequent remote commands.
115119 $ databaseHost = $ this ->resolveHostnameToIp ($ database ->getHostName ());
116120
117- $ user = $ this ->getDatabaseUser ($ responseBody ->getUserId ());
121+ $ user = $ this ->getDatabaseUser (
122+ $ responseBody ->getUserId (),
123+ (int ) get ('mittwald_database_wait ' , 30 ),
124+ (int ) get ('mittwald_database_retries ' , 20 ),
125+ );
118126
119127 $ this ->initDatabaseConfiguration ($ database , $ user , $ databaseHost );
120128 }
@@ -204,35 +212,58 @@ private function getDatabaseByFeature(string $feature): ?MySqlDatabase
204212 * @throws GuzzleException
205213 * @throws UnexpectedResponseException
206214 */
207- private function getDatabase (string $ id ): MySqlDatabase
215+ private function getDatabase (string $ id, int $ waitingTime = 10 , int $ maxRetries = 5 ): MySqlDatabase
208216 {
209- $ response = $ this ->initClient ()
210- ->database ()
211- ->getMysqlDatabase (
212- new GetMysqlDatabaseRequest (
213- mysqlDatabaseId: $ id
214- )
215- );
216-
217-
218- return $ response ->getBody ();
217+ return $ this ->retryOnUnexpectedResponse (
218+ fn () => $ this ->initClient ()
219+ ->database ()
220+ ->getMysqlDatabase (new GetMysqlDatabaseRequest (mysqlDatabaseId: $ id ))
221+ ->getBody (),
222+ 'getDatabase ' ,
223+ $ waitingTime ,
224+ $ maxRetries ,
225+ );
219226 }
220227
221228 /**
222229 * @throws GuzzleException
223230 * @throws UnexpectedResponseException
224231 */
225- private function getDatabaseUser (string $ id ): MysqlUser
232+ private function getDatabaseUser (string $ id, int $ waitingTime = 10 , int $ maxRetries = 5 ): MysqlUser
226233 {
227- $ response = $ this ->initClient ()
228- ->database ()
229- ->getMysqlUser (
230- new GetMysqlUserRequest (
231- mysqlUserId: $ id
232- )
233- );
234+ return $ this ->retryOnUnexpectedResponse (
235+ fn () => $ this ->initClient ()
236+ ->database ()
237+ ->getMysqlUser (new GetMysqlUserRequest (mysqlUserId: $ id ))
238+ ->getBody (),
239+ 'getDatabaseUser ' ,
240+ $ waitingTime ,
241+ $ maxRetries ,
242+ );
243+ }
244+
245+ /**
246+ * @template T
247+ * @param callable(): T $operation
248+ * @return T
249+ * @throws UnexpectedResponseException
250+ */
251+ private function retryOnUnexpectedResponse (callable $ operation , string $ label , int $ waitingTime , int $ maxRetries ): mixed
252+ {
253+ while ($ maxRetries > 0 ) {
254+ try {
255+ return $ operation ();
256+ } catch (UnexpectedResponseException $ e ) {
257+ $ maxRetries --;
258+ debug ("{$ label }: {$ e ->getMessage ()}, remaining attempts: {$ maxRetries }" );
259+ if ($ maxRetries <= 0 ) {
260+ throw $ e ;
261+ }
262+ sleep ($ waitingTime );
263+ }
264+ }
234265
235- return $ response -> getBody ( );
266+ throw new \ RuntimeException ( "{ $ label } failed after all retry attempts. " );
236267 }
237268
238269 private function initDatabaseConfiguration (MySqlDatabase $ database , MySqlUser $ user , string $ databaseHost ): void
0 commit comments