88//! Objects related to [`PostgresStore`] live here.
99use std:: collections:: HashMap ;
1010use std:: future:: Future ;
11- use std:: sync:: atomic:: { AtomicU64 , AtomicUsize , Ordering } ;
11+ use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
1212use std:: sync:: { Arc , Mutex } ;
1313
1414use lightning:: io;
@@ -22,6 +22,7 @@ use tokio_postgres::{Config, Error as PgError};
2222use self :: pool:: { make_config_connection, ClientConnection , PgTlsConnector , SmallPool } ;
2323use crate :: io:: utils:: check_namespace_key_validity;
2424use crate :: logger:: { log_debug, log_info, LdkLogger , Logger } ;
25+ use crate :: runtime:: StoreRuntime ;
2526
2627mod migrations;
2728mod pool;
@@ -101,8 +102,8 @@ pub struct PostgresStore {
101102 // operations aren't sensitive to the order of execution.
102103 next_write_version : AtomicU64 ,
103104
104- // A store-internal runtime used for setup and connection driver tasks .
105- internal_runtime : Option < tokio :: runtime :: Runtime > ,
105+ // A store-internal runtime that drives PostgreSQL I/O independently from the node runtime .
106+ internal_runtime : Option < Arc < StoreRuntime > > ,
106107}
107108
108109// tokio::sync::Mutex (used for the DB client) contains UnsafeCell which opts out of
@@ -145,30 +146,18 @@ impl PostgresStore {
145146 connection_string : String , db_name : Option < String > , kv_table_name : Option < String > ,
146147 certificate_pem : Option < String > , logger : Option < Arc < Logger > > ,
147148 ) -> io:: Result < Self > {
148- let internal_runtime = tokio:: runtime:: Builder :: new_multi_thread ( )
149- . enable_all ( )
150- . thread_name_fn ( || {
151- static ATOMIC_ID : AtomicUsize = AtomicUsize :: new ( 0 ) ;
152- let id = ATOMIC_ID . fetch_add ( 1 , Ordering :: SeqCst ) ;
153- format ! ( "ldk-node-postgres-runtime-{}" , id)
154- } )
155- . worker_threads ( INTERNAL_RUNTIME_WORKERS )
156- . max_blocking_threads ( INTERNAL_RUNTIME_WORKERS )
157- . build ( )
158- . map_err ( |e| {
159- io:: Error :: new (
160- io:: ErrorKind :: Other ,
161- format ! ( "Failed to build PostgreSQL runtime: {e}" ) ,
162- )
163- } ) ?;
149+ let internal_runtime = Arc :: new ( StoreRuntime :: new (
150+ "ldk-node-postgres-runtime" ,
151+ INTERNAL_RUNTIME_WORKERS ,
152+ "PostgreSQL" ,
153+ ) ?) ;
164154 let tls = Self :: build_tls_connector ( certificate_pem) ?;
165- let runtime_handle = internal_runtime. handle ( ) ;
166- let inner = tokio:: task:: block_in_place ( || {
167- runtime_handle. block_on ( async {
168- PostgresStoreInner :: new ( connection_string, db_name, kv_table_name, tls, logger)
169- . await
170- } )
171- } ) ?;
155+ let task = internal_runtime. spawn ( async move {
156+ PostgresStoreInner :: new ( connection_string, db_name, kv_table_name, tls, logger) . await
157+ } ) ;
158+ let inner = task. await . map_err ( |e| {
159+ io:: Error :: new ( io:: ErrorKind :: Other , format ! ( "PostgreSQL runtime task failed: {}" , e) )
160+ } ) ??;
172161 let inner = Arc :: new ( inner) ;
173162 let next_write_version = AtomicU64 :: new ( 1 ) ;
174163 Ok ( Self { inner, next_write_version, internal_runtime : Some ( internal_runtime) } )
@@ -214,12 +203,18 @@ impl PostgresStore {
214203
215204 ( inner_lock_ref, version)
216205 }
206+
207+ fn internal_runtime ( & self ) -> Arc < StoreRuntime > {
208+ Arc :: clone ( self . internal_runtime . as_ref ( ) . expect ( "PostgreSQL runtime must be available" ) )
209+ }
217210}
218211
219212impl Drop for PostgresStore {
220213 fn drop ( & mut self ) {
221214 if let Some ( internal_runtime) = self . internal_runtime . take ( ) {
222- internal_runtime. shutdown_background ( ) ;
215+ if let Ok ( internal_runtime) = Arc :: try_unwrap ( internal_runtime) {
216+ internal_runtime. shutdown_background ( ) ;
217+ }
223218 }
224219 }
225220}
@@ -232,7 +227,18 @@ impl KVStore for PostgresStore {
232227 let secondary_namespace = secondary_namespace. to_string ( ) ;
233228 let key = key. to_string ( ) ;
234229 let inner = Arc :: clone ( & self . inner ) ;
235- async move { inner. read_internal ( & primary_namespace, & secondary_namespace, & key) . await }
230+ let runtime = self . internal_runtime ( ) ;
231+ async move {
232+ let task = runtime. spawn ( async move {
233+ inner. read_internal ( & primary_namespace, & secondary_namespace, & key) . await
234+ } ) ;
235+ task. await . map_err ( |e| {
236+ io:: Error :: new (
237+ io:: ErrorKind :: Other ,
238+ format ! ( "PostgreSQL runtime task failed: {}" , e) ,
239+ )
240+ } ) ?
241+ }
236242 }
237243
238244 fn write (
@@ -244,18 +250,27 @@ impl KVStore for PostgresStore {
244250 let secondary_namespace = secondary_namespace. to_string ( ) ;
245251 let key = key. to_string ( ) ;
246252 let inner = Arc :: clone ( & self . inner ) ;
253+ let runtime = self . internal_runtime ( ) ;
247254 async move {
248- inner
249- . write_internal (
250- inner_lock_ref,
251- locking_key,
252- version,
253- & primary_namespace,
254- & secondary_namespace,
255- & key,
256- buf,
255+ let task = runtime. spawn ( async move {
256+ inner
257+ . write_internal (
258+ inner_lock_ref,
259+ locking_key,
260+ version,
261+ & primary_namespace,
262+ & secondary_namespace,
263+ & key,
264+ buf,
265+ )
266+ . await
267+ } ) ;
268+ task. await . map_err ( |e| {
269+ io:: Error :: new (
270+ io:: ErrorKind :: Other ,
271+ format ! ( "PostgreSQL runtime task failed: {}" , e) ,
257272 )
258- . await
273+ } ) ?
259274 }
260275 }
261276
@@ -268,17 +283,26 @@ impl KVStore for PostgresStore {
268283 let secondary_namespace = secondary_namespace. to_string ( ) ;
269284 let key = key. to_string ( ) ;
270285 let inner = Arc :: clone ( & self . inner ) ;
286+ let runtime = self . internal_runtime ( ) ;
271287 async move {
272- inner
273- . remove_internal (
274- inner_lock_ref,
275- locking_key,
276- version,
277- & primary_namespace,
278- & secondary_namespace,
279- & key,
288+ let task = runtime. spawn ( async move {
289+ inner
290+ . remove_internal (
291+ inner_lock_ref,
292+ locking_key,
293+ version,
294+ & primary_namespace,
295+ & secondary_namespace,
296+ & key,
297+ )
298+ . await
299+ } ) ;
300+ task. await . map_err ( |e| {
301+ io:: Error :: new (
302+ io:: ErrorKind :: Other ,
303+ format ! ( "PostgreSQL runtime task failed: {}" , e) ,
280304 )
281- . await
305+ } ) ?
282306 }
283307 }
284308
@@ -288,16 +312,18 @@ impl KVStore for PostgresStore {
288312 let primary_namespace = primary_namespace. to_string ( ) ;
289313 let secondary_namespace = secondary_namespace. to_string ( ) ;
290314 let inner = Arc :: clone ( & self . inner ) ;
291- async move { inner. list_internal ( & primary_namespace, & secondary_namespace) . await }
292- }
293- }
294-
295- impl PostgresStore {
296- fn internal_runtime ( & self ) -> io:: Result < & tokio:: runtime:: Runtime > {
297- self . internal_runtime . as_ref ( ) . ok_or_else ( || {
298- debug_assert ! ( false , "Failed to access internal PostgreSQL runtime" ) ;
299- io:: Error :: new ( io:: ErrorKind :: Other , "Failed to access internal PostgreSQL runtime" )
300- } )
315+ let runtime = self . internal_runtime ( ) ;
316+ async move {
317+ let task = runtime. spawn ( async move {
318+ inner. list_internal ( & primary_namespace, & secondary_namespace) . await
319+ } ) ;
320+ task. await . map_err ( |e| {
321+ io:: Error :: new (
322+ io:: ErrorKind :: Other ,
323+ format ! ( "PostgreSQL runtime task failed: {}" , e) ,
324+ )
325+ } ) ?
326+ }
301327 }
302328}
303329
@@ -308,10 +334,19 @@ impl PaginatedKVStore for PostgresStore {
308334 let primary_namespace = primary_namespace. to_string ( ) ;
309335 let secondary_namespace = secondary_namespace. to_string ( ) ;
310336 let inner = Arc :: clone ( & self . inner ) ;
337+ let runtime = self . internal_runtime ( ) ;
311338 async move {
312- inner
313- . list_paginated_internal ( & primary_namespace, & secondary_namespace, page_token)
314- . await
339+ let task = runtime. spawn ( async move {
340+ inner
341+ . list_paginated_internal ( & primary_namespace, & secondary_namespace, page_token)
342+ . await
343+ } ) ;
344+ task. await . map_err ( |e| {
345+ io:: Error :: new (
346+ io:: ErrorKind :: Other ,
347+ format ! ( "PostgreSQL runtime task failed: {}" , e) ,
348+ )
349+ } ) ?
315350 }
316351 }
317352}
0 commit comments