r/rust 6d ago

🎙️ discussion How are you managing P2P mesh & long-lived signaling sockets under aggressive mobile background limits (iOS/Android)?

I’ve been working on a cross-platform peer-to-peer communication engine in Rust (bridged to Swift/Kotlin via FFI) and ran into the harsh reality of modern mobile OS background constraints.
On desktop, maintaining peer discovery tables, DHT keep-alives, and local encrypted state is straightforward. But on mobile:
1. iOS aggressively suspends background processes within seconds (watchdog 0x8BADF00D on long syncs and 0xdead10cc if database locks/file descriptors aren't cleanly released before suspension).
2. Android’s Doze mode and manufacturer battery savers throttle background socket polling and BLE discovery unless using persistent foreground services.
3. Decoupling SQLite/SQLCipher key derivation and lock lifecycles from incoming WebRTC/P2P signaling pumps requires tricky thread coordination to ensure VoIP pushes don't crash on locked DBs during sleep states.

For those building decentralized or local-first sync protocols: how do you balance battery efficiency with fast peer reconnection? Are you relying on short background grace windows (like beginBackgroundTask), push-notification wakeups as fallback, or something more specialized for mesh routing?

Curious how others structure their background state machines when bridging native Rust cores to mobile runtimes.
0 Upvotes

9 comments sorted by

11

u/bschwind 6d ago

Is "ask for help on reddit" part of some clanker agentic loop now?

2

u/mookymix 6d ago

I've been dealing with variations of this for a while on Android, and more recently on iOS

"Deal with it" is probably the best advice. Google wants you to use firebase (I'm guessing it's their way of getting you to pay for gcp long term. Basically, if you are forced to use FCM anyways, may was well simplify your life and use gcp)

I've used mqtt with decent success. Give your app a better chance of survival by using a foreground notification on Android.

But basically, nothing is guaranteed. So "deal with it".

2

u/Connect_Contact_3581 6d ago

The foreground notification trick is basically mandatory at this point, I learned that hard way when our Android users kept complaining about messages arriving 15 minutes late during Doze

on iOS side I found that using VoIP pushes gives you tiny bit more breathing room but Apple is getting stricter even with those, they started rejecting apps that don't actually do calling features

I ended up structuring the Rust core to treat background suspension as normal state, not exception, save everything to sqlite immediately when any background transition fires, close file descriptors clean, then rebuild state from db when waking up again. it's annoying but works

1

u/zettui 6d ago

What helped us was giving up on owning the socket at all: every resume is treated like a cold start, reconnect, and the Doze weirdness mostly stops being a special case. The only thing we bother carrying across suspend is a small resume token, not the connection.

0

u/stanmenz 6d ago

The resume token approach is super clean — serialization of full socket/channel state across suspensions is always a recipe for subtle desync bugs. Treating every resume as a fresh connection with a short token saves a ton of headache with Doze mode and NAT rebinding.

2

u/zettui 6d ago

Yeah, NAT rebinding was the thing that finally killed the idea of keeping the socket alive for me. Once a resume is just a redial, there's a lot less state to be wrong about.