Skip to content

Commit e1ba7ff

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 72f49e5 commit e1ba7ff

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
@@ -116,6 +116,13 @@ const FIRST_NETWORK_PRUNE_TIMER: u64 = 60;
116116
#[cfg(test)]
117117
const FIRST_NETWORK_PRUNE_TIMER: u64 = 1;
118118

119+
#[cfg(feature = "futures")]
120+
/// core::cmp::min is not currently const, so we define a trivial (and equivalent) replacement
121+
const fn min_u64(a: u64, b: u64) -> u64 { if a < b { a } else { b } }
122+
#[cfg(feature = "futures")]
123+
const FASTEST_TIMER: u64 = min_u64(min_u64(FRESHNESS_TIMER, PING_TIMER),
124+
min_u64(SCORER_PERSIST_TIMER, FIRST_NETWORK_PRUNE_TIMER));
125+
119126
/// Either [`P2PGossipSync`] or [`RapidGossipSync`].
120127
pub enum GossipSync<
121128
P: Deref<Target = P2PGossipSync<G, U, L>>,
@@ -258,7 +265,8 @@ macro_rules! define_run_body {
258265
($persister: ident, $chain_monitor: ident, $process_chain_monitor_events: expr,
259266
$channel_manager: ident, $process_channel_manager_events: expr,
260267
$gossip_sync: ident, $peer_manager: ident, $logger: ident, $scorer: ident,
261-
$loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr)
268+
$loop_exit_check: expr, $await: expr, $get_timer: expr, $timer_elapsed: expr,
269+
$check_slow_await: expr)
262270
=> { {
263271
log_trace!($logger, "Calling ChannelManager's timer_tick_occurred on startup");
264272
$channel_manager.timer_tick_occurred();
@@ -288,9 +296,10 @@ macro_rules! define_run_body {
288296

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

295304
if updates_available {
296305
log_trace!($logger, "Persisting ChannelManager...");
@@ -449,6 +458,11 @@ use core::task;
449458
/// feature, doing so will skip calling [`NetworkGraph::remove_stale_channels_and_tracking`],
450459
/// you should call [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] regularly
451460
/// manually instead.
461+
///
462+
/// The `mobile_interruptable_platform` flag should be set if we're currently running on a
463+
/// mobile device, where we may need to check for interruption of the application regularly. If you
464+
/// are unsure, you should set the flag, as the performance impact of it is minimal unless there
465+
/// are hundreds or thousands of simultaneous process calls running.
452466
#[cfg(feature = "futures")]
453467
pub async fn process_events_async<
454468
'a,
@@ -484,7 +498,7 @@ pub async fn process_events_async<
484498
>(
485499
persister: PS, event_handler: EventHandler, chain_monitor: M, channel_manager: CM,
486500
gossip_sync: GossipSync<PGS, RGS, G, UL, L>, peer_manager: PM, logger: L, scorer: Option<S>,
487-
sleeper: Sleeper,
501+
sleeper: Sleeper, mobile_interruptable_platform: bool,
488502
) -> Result<(), lightning::io::Error>
489503
where
490504
UL::Target: 'static + UtxoLookup,
@@ -526,7 +540,7 @@ where
526540
let fut = Selector {
527541
a: channel_manager.get_persistable_update_future(),
528542
b: chain_monitor.get_update_future(),
529-
c: sleeper(Duration::from_millis(100)),
543+
c: sleeper(if mobile_interruptable_platform { Duration::from_millis(100) } else { Duration::from_secs(FASTEST_TIMER) }),
530544
};
531545
match fut.await {
532546
SelectorOutput::A => true,
@@ -541,7 +555,7 @@ where
541555
let mut waker = dummy_waker();
542556
let mut ctx = task::Context::from_waker(&mut waker);
543557
core::pin::Pin::new(fut).poll(&mut ctx).is_ready()
544-
})
558+
}, mobile_interruptable_platform)
545559
}
546560

547561
#[cfg(feature = "std")]
@@ -660,7 +674,7 @@ impl BackgroundProcessor {
660674
channel_manager.get_persistable_update_future(),
661675
chain_monitor.get_update_future()
662676
).wait_timeout(Duration::from_millis(100)),
663-
|_| Instant::now(), |time: &Instant, dur| time.elapsed().as_secs() > dur)
677+
|_| Instant::now(), |time: &Instant, dur| time.elapsed().as_secs() > dur, false)
664678
});
665679
Self { stop_thread: stop_thread_clone, thread_handle: Some(handle) }
666680
}

0 commit comments

Comments
 (0)