@@ -41,9 +41,7 @@ use std::ops::Deref;
41
41
/// for unilateral chain closure fees are at risk.
42
42
pub struct BackgroundProcessor {
43
43
stop_thread : Arc < AtomicBool > ,
44
- /// May be used to retrieve and handle the error if `BackgroundProcessor`'s thread
45
- /// exits due to an error while persisting.
46
- pub thread_handle : JoinHandle < Result < ( ) , std:: io:: Error > > ,
44
+ thread_handle : Option < JoinHandle < Result < ( ) , std:: io:: Error > > > ,
47
45
}
48
46
49
47
#[ cfg( not( test) ) ]
@@ -84,21 +82,25 @@ ChannelManagerPersister<Signer, M, T, K, F, L> for Fun where
84
82
}
85
83
86
84
impl BackgroundProcessor {
87
- /// Start a background thread that takes care of responsibilities enumerated in the top-level
88
- /// documentation.
85
+ /// Start a background thread that takes care of responsibilities enumerated in the [ top-level
86
+ /// documentation] .
89
87
///
90
- /// If `persist_manager` returns an error, then this thread will return said error (and
91
- /// `start()` will need to be called again to restart the `BackgroundProcessor`). Users should
92
- /// wait on [`thread_handle`]'s `join()` method to be able to tell if and when an error is
93
- /// returned, or implement `persist_manager` such that an error is never returned to the
94
- /// `BackgroundProcessor`
88
+ /// The thread runs indefinitely unless the object is dropped, [`stop`] is called, or
89
+ /// `persist_manager` returns an error. In case of an error, the error is retrieved by calling
90
+ /// either [`join`] or [`stop`].
91
+ ///
92
+ /// Typically, users should either implement [`ChannelManagerPersister`] to never return an
93
+ /// error or call [`join`] and handle any error that may arise. For the latter case, the
94
+ /// `BackgroundProcessor` must be restarted by calling `start` again after handling the error.
95
95
///
96
96
/// `persist_manager` is responsible for writing out the [`ChannelManager`] to disk, and/or
97
97
/// uploading to one or more backup services. See [`ChannelManager::write`] for writing out a
98
98
/// [`ChannelManager`]. See [`FilesystemPersister::persist_manager`] for Rust-Lightning's
99
99
/// provided implementation.
100
100
///
101
- /// [`thread_handle`]: BackgroundProcessor::thread_handle
101
+ /// [top-level documentation]: Self
102
+ /// [`join`]: Self::join
103
+ /// [`stop`]: Self::stop
102
104
/// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
103
105
/// [`ChannelManager::write`]: lightning::ln::channelmanager::ChannelManager#impl-Writeable
104
106
/// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister::persist_manager
@@ -158,13 +160,53 @@ impl BackgroundProcessor {
158
160
}
159
161
}
160
162
} ) ;
161
- Self { stop_thread : stop_thread_clone, thread_handle : handle }
163
+ Self { stop_thread : stop_thread_clone, thread_handle : Some ( handle) }
164
+ }
165
+
166
+ /// Join `BackgroundProcessor`'s thread, returning any error that occurred while persisting
167
+ /// [`ChannelManager`].
168
+ ///
169
+ /// # Panics
170
+ ///
171
+ /// This function panics if the background thread has panicked such as while persisting or
172
+ /// handling events.
173
+ ///
174
+ /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
175
+ pub fn join ( mut self ) -> Result < ( ) , std:: io:: Error > {
176
+ assert ! ( self . thread_handle. is_some( ) ) ;
177
+ self . join_thread ( )
178
+ }
179
+
180
+ /// Stop `BackgroundProcessor`'s thread, returning any error that occurred while persisting
181
+ /// [`ChannelManager`].
182
+ ///
183
+ /// # Panics
184
+ ///
185
+ /// This function panics if the background thread has panicked such as while persisting or
186
+ /// handling events.
187
+ ///
188
+ /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
189
+ pub fn stop ( mut self ) -> Result < ( ) , std:: io:: Error > {
190
+ assert ! ( self . thread_handle. is_some( ) ) ;
191
+ self . stop_and_join_thread ( )
162
192
}
163
193
164
- /// Stop `BackgroundProcessor`'s thread.
165
- pub fn stop ( self ) -> Result < ( ) , std:: io:: Error > {
194
+ fn stop_and_join_thread ( & mut self ) -> Result < ( ) , std:: io:: Error > {
166
195
self . stop_thread . store ( true , Ordering :: Release ) ;
167
- self . thread_handle . join ( ) . unwrap ( )
196
+ self . join_thread ( )
197
+ }
198
+
199
+ fn join_thread ( & mut self ) -> Result < ( ) , std:: io:: Error > {
200
+ match self . thread_handle . take ( ) {
201
+ Some ( handle) => handle. join ( ) . unwrap ( ) ,
202
+ None => Ok ( ( ) ) ,
203
+ }
204
+ }
205
+ }
206
+
207
+ impl Drop for BackgroundProcessor {
208
+ fn drop ( & mut self ) {
209
+ self . stop_and_join_thread ( ) . unwrap ( ) ;
168
210
}
169
211
}
170
212
@@ -416,7 +458,13 @@ mod tests {
416
458
let persister = |_: & _ | Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "test" ) ) ;
417
459
let event_handler = |_| { } ;
418
460
let bg_processor = BackgroundProcessor :: start ( persister, event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
419
- let _ = bg_processor. thread_handle . join ( ) . unwrap ( ) . expect_err ( "Errored persisting manager: test" ) ;
461
+ match bg_processor. join ( ) {
462
+ Ok ( _) => panic ! ( "Expected error persisting manager" ) ,
463
+ Err ( e) => {
464
+ assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: Other ) ;
465
+ assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "test" ) ;
466
+ } ,
467
+ }
420
468
}
421
469
422
470
#[ test]
0 commit comments