@@ -28,12 +28,12 @@ impl Database {
2828 let mut options = database_url. parse :: < SqliteConnectOptions > ( ) ?;
2929 options = set_common_connect_options ( options) ;
3030 options = set_custom_connect_options_sqlite ( options, config) ;
31- let pool = Self :: create_sqlite_pool_options ( config , db_kind )
32- . connect_with ( options )
33- . await
34- . with_context ( || {
35- format ! ( "Unable to open connection pool to {}" , config . database_url )
36- } ) ?;
31+ let pool = connect_pool_with_retries (
32+ Self :: create_sqlite_pool_options ( config , db_kind ) ,
33+ options ,
34+ config ,
35+ )
36+ . await ?;
3737 DatabasePool :: Sqlite ( pool)
3838 }
3939 DbKind :: Postgres => {
@@ -42,12 +42,12 @@ impl Database {
4242 options = options. password ( password) ;
4343 }
4444 options = set_common_connect_options ( options) ;
45- let pool = Self :: create_pool_options :: < sqlx :: Postgres > ( config , db_kind )
46- . connect_with ( options )
47- . await
48- . with_context ( || {
49- format ! ( "Unable to open connection pool to {}" , config . database_url )
50- } ) ?;
45+ let pool = connect_pool_with_retries (
46+ Self :: create_pool_options :: < sqlx :: Postgres > ( config , db_kind ) ,
47+ options ,
48+ config ,
49+ )
50+ . await ?;
5151 DatabasePool :: Postgres ( pool)
5252 }
5353 DbKind :: MySql => {
@@ -56,12 +56,12 @@ impl Database {
5656 options = options. password ( password) ;
5757 }
5858 options = set_common_connect_options ( options) ;
59- let pool = Self :: create_pool_options :: < sqlx :: MySql > ( config , db_kind )
60- . connect_with ( options )
61- . await
62- . with_context ( || {
63- format ! ( "Unable to open connection pool to {}" , config . database_url )
64- } ) ?;
59+ let pool = connect_pool_with_retries (
60+ Self :: create_pool_options :: < sqlx :: MySql > ( config , db_kind ) ,
61+ options ,
62+ config ,
63+ )
64+ . await ?;
6565 DatabasePool :: MySql ( pool)
6666 }
6767 DbKind :: Mssql => {
@@ -70,12 +70,12 @@ impl Database {
7070 . parse :: < MssqlConnectOptions > ( )
7171 . with_context ( || format ! ( "Unable to parse {}" , config. database_url) ) ?,
7272 ) ;
73- let pool = Self :: create_pool_options :: < sqlx_sqlserver :: Mssql > ( config , db_kind )
74- . connect_with ( options )
75- . await
76- . with_context ( || {
77- format ! ( "Unable to open connection pool to {}" , config . database_url )
78- } ) ?;
73+ let pool = connect_pool_with_retries (
74+ Self :: create_pool_options :: < sqlx_sqlserver :: Mssql > ( config , db_kind ) ,
75+ options ,
76+ config ,
77+ )
78+ . await ?;
7979 DatabasePool :: Mssql ( pool)
8080 }
8181 DbKind :: Odbc => {
@@ -89,12 +89,12 @@ impl Database {
8989 let dbms_name = detect_odbc_dbms_name ( & options, config) . await ?;
9090 let database_type = SupportedDatabase :: from_dbms_name ( & dbms_name) ;
9191 let options = set_common_connect_options ( options) ;
92- let pool = Self :: create_pool_options :: < sqlx_odbc :: Odbc > ( config , db_kind )
93- . connect_with ( options )
94- . await
95- . with_context ( || {
96- format ! ( "Unable to open connection pool to {}" , config . database_url )
97- } ) ?;
92+ let pool = connect_pool_with_retries (
93+ Self :: create_pool_options :: < sqlx_odbc :: Odbc > ( config , db_kind ) ,
94+ options ,
95+ config ,
96+ )
97+ . await ?;
9898 log:: debug!( "Initialized {dbms_name:?} database pool: {pool:#?}" ) ;
9999 return Ok ( Database {
100100 connection : DatabasePool :: Odbc ( pool) ,
@@ -157,6 +157,33 @@ impl Database {
157157 }
158158}
159159
160+ async fn connect_pool_with_retries < DB > (
161+ pool_options : PoolOptions < DB > ,
162+ options : <DB :: Connection as Connection >:: Options ,
163+ config : & AppConfig ,
164+ ) -> anyhow:: Result < sqlx:: Pool < DB > >
165+ where
166+ DB : SqlxDatabase ,
167+ {
168+ let mut retries = config. database_connection_retries ;
169+ loop {
170+ match pool_options. clone ( ) . connect_with ( options. clone ( ) ) . await {
171+ Ok ( pool) => return Ok ( pool) ,
172+ Err ( e) => {
173+ if retries == 0 {
174+ return Err ( anyhow:: Error :: new ( e) . context ( format ! (
175+ "Unable to open connection pool to {}" ,
176+ config. database_url
177+ ) ) ) ;
178+ }
179+ log:: warn!( "Failed to connect to the database: {e:#}. Retrying in 5 seconds." ) ;
180+ retries -= 1 ;
181+ tokio:: time:: sleep ( Duration :: from_secs ( 5 ) ) . await ;
182+ }
183+ }
184+ }
185+ }
186+
160187fn default_max_connections ( config : & AppConfig , kind : DbKind ) -> u32 {
161188 match kind {
162189 DbKind :: Postgres | DbKind :: Odbc => 50 ,
0 commit comments