1
+ #[ macro_use] extern crate lightning;
2
+
1
3
use lightning:: chain;
2
4
use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator } ;
3
5
use lightning:: chain:: keysinterface:: { ChannelKeys , KeysInterface } ;
4
6
use lightning:: ln:: channelmanager:: ChannelManager ;
5
- use lightning:: { log_internal, log_trace} ;
6
7
use lightning:: util:: logger:: Logger ;
7
8
use lightning:: util:: ser:: Writeable ;
8
9
use std:: sync:: Arc ;
@@ -28,14 +29,7 @@ pub struct BackgroundProcessor {
28
29
stop_thread : Arc < AtomicBool > ,
29
30
/// May be used to retrieve and handle the error if `BackgroundProcessor`'s thread
30
31
/// panics.
31
- pub thread_handle : JoinHandle < ( ) >
32
- }
33
-
34
- // Re-export these modules for the logging macros.
35
- mod util {
36
- pub ( crate ) mod logger {
37
- pub ( crate ) use lightning:: util:: logger:: Record ;
38
- }
32
+ pub thread_handle : JoinHandle < Result < ( ) , std:: io:: Error > >
39
33
}
40
34
41
35
#[ cfg( not( test) ) ]
@@ -45,25 +39,20 @@ const CHAN_FRESHNESS_TIMER: u64 = 1;
45
39
46
40
impl BackgroundProcessor {
47
41
/// Start a background thread that takes care of responsibilities enumerated in the top-level
48
- /// documentation. Marked as `must_use` because otherwise the result is dropped immediately,
49
- /// resulting in the thread being terminated.
50
- /// Important note: this thread will panic if invoking `persist_manager` results in an error (and
51
- /// `start()` will need to be called again to restart the `BackgroundProcessor`).
52
- /// There are 3 main options for handling this panic:
53
- /// * wait on [`thread_handle`]'s `join()`, handle the error
54
- /// * [configure] to abort on panic
55
- /// * write a custom `persist_manager` to handle the error so it never gets returned to
56
- /// `BackgroundProcessor`.
42
+ /// documentation.
43
+ ///
44
+ /// If `persist_manager` returns an error, then this thread will return said error (and `start()`
45
+ /// will need to be called again to restart the `BackgroundProcessor`). Users should wait on
46
+ /// [`thread_handle`]'s `join()` method to be able to tell if and when an error is returned, or
47
+ /// implement `persist_manager` such that an error is never returned to the `BackgroundProcessor`
57
48
///
58
49
/// `persist_manager` is responsible for writing out the `ChannelManager` to disk, and/or uploading
59
50
/// to one or more backup services. See [`ChannelManager::write`] for writing out a `ChannelManager`.
60
51
/// See [`FilesystemPersister::persist_manager`] for Rust-Lightning's provided implementation.
61
52
///
62
53
/// [`thread_handle`]: struct.BackgroundProcessor.html#structfield.thread_handle
63
- /// [configure]: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/aborting-on-panic.html
64
54
/// [`ChannelManager::write`]: ../lightning/ln/channelmanager/struct.ChannelManager.html#method.write
65
55
/// [`FilesystemPersister::persist_manager`]: ../lightning_persister/struct.FilesystemPersister.html#impl
66
- #[ must_use]
67
56
pub fn start < PM , ChanSigner , M , T , K , F , L > ( persist_manager : PM , manager : Arc < ChannelManager < ChanSigner , Arc < M > , Arc < T > , Arc < K > , Arc < F > , Arc < L > > > , logger : Arc < L > ) -> Self
68
57
where ChanSigner : ' static + ChannelKeys + Writeable ,
69
58
M : ' static + chain:: Watch < Keys =ChanSigner > ,
@@ -75,19 +64,17 @@ impl BackgroundProcessor {
75
64
{
76
65
let stop_thread = Arc :: new ( AtomicBool :: new ( false ) ) ;
77
66
let stop_thread_clone = stop_thread. clone ( ) ;
78
- let handle = thread:: spawn ( move || {
67
+ let handle = thread:: spawn ( move || -> Result < ( ) , std :: io :: Error > {
79
68
let mut current_time = Instant :: now ( ) ;
80
69
loop {
81
70
let updates_available = manager. wait_timeout ( Duration :: from_millis ( 100 ) ) ;
82
71
if updates_available {
83
- if let Err ( e) = persist_manager ( manager. clone ( ) ) {
84
- panic ! ( "Errored persisting manager: {}" , e) ;
85
- } ;
72
+ persist_manager ( manager. clone ( ) ) ?;
86
73
}
87
74
// Exit the loop if the background processor was requested to stop.
88
75
if stop_thread. load ( Ordering :: Acquire ) == true {
89
76
log_trace ! ( logger, "Terminating background processor." ) ;
90
- break ;
77
+ return Ok ( ( ) )
91
78
}
92
79
if current_time. elapsed ( ) . as_secs ( ) > CHAN_FRESHNESS_TIMER {
93
80
log_trace ! ( logger, "Calling manager's timer_chan_freshness_every_min" ) ;
@@ -217,7 +204,7 @@ mod tests {
217
204
// Initiate the background processors to watch each node.
218
205
let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
219
206
let callback = move |node| FilesystemPersister :: persist_manager ( data_dir. clone ( ) , node) ;
220
- let _processor = BackgroundProcessor :: start ( callback, nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
207
+ BackgroundProcessor :: start ( callback, nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
221
208
222
209
// Go through the channel creation process until each node should have something persisted.
223
210
let tx = open_channel ! ( nodes[ 0 ] , nodes[ 1 ] , 100000 ) ;
@@ -270,7 +257,7 @@ mod tests {
270
257
let nodes = create_nodes ( 1 , "test_chan_freshness_called" . to_string ( ) ) ;
271
258
let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
272
259
let callback = move |node| FilesystemPersister :: persist_manager ( data_dir. clone ( ) , node) ;
273
- let processor = BackgroundProcessor :: start ( callback, nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
260
+ BackgroundProcessor :: start ( callback, nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
274
261
loop {
275
262
let log_entries = nodes[ 0 ] . logger . lines . lock ( ) . unwrap ( ) ;
276
263
let desired_log = "Calling manager's timer_chan_freshness_every_min" . to_string ( ) ;
@@ -294,16 +281,6 @@ mod tests {
294
281
Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "test" ) )
295
282
}
296
283
297
- // We don't want the expected panic to print to the console during testing, so
298
- // swallow it here.
299
- std:: panic:: set_hook ( Box :: new ( |panic_info| {
300
- if let Some ( s) = panic_info. payload ( ) . downcast_ref :: < String > ( ) {
301
- assert_eq ! ( s, "Errored persisting manager: test" ) ;
302
- } else {
303
- panic ! ( "Expected string panic" ) ;
304
- }
305
- } ) ) ;
306
-
307
284
let nodes = create_nodes ( 2 , "test_persist_error" . to_string ( ) ) ;
308
285
let bg_processor = BackgroundProcessor :: start ( persist_manager, nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
309
286
open_channel ! ( nodes[ 0 ] , nodes[ 1 ] , 100000 ) ;
0 commit comments