Skip to content

Commit 003be28

Browse files
committed
Expose an option to substantially reduce sleep time in futures BP
Some users have suggested that waking every 100ms can be CPU-intensive in deployments with hundreds or thousands of nodes all running on the same machine. Thus, we add an option to the futures-based `background-processor` to avoid waking every 100ms to check for iOS having backgrounded our app and cut our TCP sockets. This cuts the normal sleep time down from 100ms to 10s, for those who turn it on.
1 parent 2584c24 commit 003be28

File tree

1 file changed

+21
-7
lines changed
  • lightning-background-processor/src

1 file changed

+21
-7
lines changed

lightning-background-processor/src/lib.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 60;
118118
#[cfg(test)]
119119
const FIRST_NETWORK_PRUNE_TIMER: u64 = 1;
120120

121+
#[cfg(feature = "futures")]
122+
/// core::cmp::min is not currently const, so we define a trivial (and equivalent) replacement
123+
const fn min_u64(a: u64, b: u64) -> u64 { if a < b { a } else { b } }
124+
#[cfg(feature = "futures")]
125+
const FASTEST_TIMER: u64 = min_u64(min_u64(FRESHNESS_TIMER, PING_TIMER),
126+
min_u64(SCORER_PERSIST_TIMER, FIRST_NETWORK_PRUNE_TIMER));
127+
121128
/// Either [`P2PGossipSync`] or [`RapidGossipSync`].
122129
pub enum GossipSync<
123130
P: Deref<Target = P2PGossipSync<G, U, L>>,
@@ -260,7 +267,8 @@ macro_rules! define_run_body {
260267
($persister: ident, $chain_monitor: ident, $process_chain_monitor_events: expr,
261268
$channel_manager: ident, $process_channel_manager_events: expr,
262269
$gossip_sync: ident, $peer_manager: ident, $logger: ident, $scorer: ident,
263-
$loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr)
270+
$loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr,
271+
$check_slow_await: expr)
264272
=> { {
265273
log_trace!($logger, "Calling ChannelManager's timer_tick_occurred on startup");
266274
$channel_manager.timer_tick_occurred();
@@ -290,9 +298,10 @@ macro_rules! define_run_body {
290298

291299
// We wait up to 100ms, but track how long it takes to detect being put to sleep,
292300
// see `await_start`'s use below.
293-
let mut await_start = $get_timer(1);
301+
let mut await_start = None;
302+
if $check_slow_await { await_start = Some($get_timer(1)); }
294303
let updates_available = $await;
295-
let await_slow = $timer_elapsed(&mut await_start, 1);
304+
let await_slow = if $check_slow_await { $timer_elapsed(&mut await_start.unwrap(), 1) } else { false };
296305

297306
if updates_available {
298307
log_trace!($logger, "Persisting ChannelManager...");
@@ -398,6 +407,11 @@ macro_rules! define_run_body {
398407
/// feature, doing so will skip calling [`NetworkGraph::remove_stale_channels_and_tracking`],
399408
/// you should call [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] regularly
400409
/// manually instead.
410+
///
411+
/// The `mobile_interruptable_platform` flag should be set if we're currently running on a
412+
/// mobile device, where we may need to check for interruption of the application regularly. If you
413+
/// are unsure, you should set the flag, as the performance impact of it is minimal unless there
414+
/// are hundreds or thousands of simultaneous process calls running.
401415
#[cfg(feature = "futures")]
402416
pub async fn process_events_async<
403417
'a,
@@ -433,7 +447,7 @@ pub async fn process_events_async<
433447
>(
434448
persister: PS, event_handler: EventHandler, chain_monitor: M, channel_manager: CM,
435449
gossip_sync: GossipSync<PGS, RGS, G, UL, L>, peer_manager: PM, logger: L, scorer: Option<S>,
436-
sleeper: Sleeper,
450+
sleeper: Sleeper, mobile_interruptable_platform: bool,
437451
) -> Result<(), lightning::io::Error>
438452
where
439453
UL::Target: 'static + UtxoLookup,
@@ -475,7 +489,7 @@ where
475489
select_biased! {
476490
_ = chain_monitor.get_update_future().fuse() => true,
477491
_ = channel_manager.get_persistable_update_future().fuse() => false,
478-
exit = sleeper(Duration::from_millis(100)).fuse() => {
492+
exit = sleeper(if mobile_interruptable_platform { Duration::from_millis(100) } else { Duration::from_secs(FASTEST_TIMER) }).fuse() => {
479493
should_break = exit;
480494
false
481495
}
@@ -485,7 +499,7 @@ where
485499
let mut waker = task::noop_waker();
486500
let mut ctx = task::Context::from_waker(&mut waker);
487501
core::pin::Pin::new(fut).poll(&mut ctx).is_ready()
488-
})
502+
}, mobile_interruptable_platform)
489503
}
490504

491505
#[cfg(feature = "std")]
@@ -604,7 +618,7 @@ impl BackgroundProcessor {
604618
channel_manager.get_persistable_update_future(),
605619
chain_monitor.get_update_future()
606620
).wait_timeout(Duration::from_millis(100)),
607-
|_| Instant::now(), |time: &Instant, dur| time.elapsed().as_secs() > dur)
621+
|_| Instant::now(), |time: &Instant, dur| time.elapsed().as_secs() > dur, false)
608622
});
609623
Self { stop_thread: stop_thread_clone, thread_handle: Some(handle) }
610624
}

0 commit comments

Comments
 (0)