feat: use tentacle spawn feature#1164
feat: use tentacle spawn feature#1164driftluo wants to merge 2 commits intonervosnetwork:developfrom
Conversation
eb3fe7c to
4b312c1
Compare
4b312c1 to
dbb481d
Compare
There was a problem hiding this comment.
Pull request overview
Switches Fiber/Gossip protocols to Tentacle’s ProtocolSpawn model so per-session protocol handling is spawned on demand, delaying initialization until the first connection and avoiding ServiceHandle aggregation.
Changes:
- Replaced
ServiceProtocolcallbacks withProtocolSpawnimplementations that read fromSubstreamReadPart. - Introduced
SharedControl(Arc) to shareServiceAsyncControlacross clones and initialize once. - Enabled Tentacle’s
unstablefeature to access the spawn API.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| crates/fiber-lib/src/fiber/network.rs | Migrates Fiber protocol handling to ProtocolSpawn and reads messages from SubstreamReadPart. |
| crates/fiber-lib/src/fiber/gossip.rs | Migrates Gossip protocol handling to ProtocolSpawn, delays control initialization via SharedControl, and adds unit tests for SharedControl. |
| crates/fiber-lib/Cargo.toml | Enables Tentacle unstable feature required for spawn-based APIs. |
| fn get_control(&self) -> &ServiceAsyncControl { | ||
| self.control.as_ref().expect("control exists") | ||
| self.control.get().expect("control exists") | ||
| } |
There was a problem hiding this comment.
control is now set in ProtocolSpawn::spawn, which (per PR description) can be delayed until the first connection. Any actor code path that calls get_control() before the first spawn (e.g., interval ticks started in pre_start) will panic. Consider changing get_control() to return Option<&ServiceAsyncControl> (or Result) and make tick handlers/no-connection code paths no-op until control is available (or start the intervals only after control is set).
| control: &ServiceAsyncControl, | ||
| mut read_part: SubstreamReadPart, | ||
| ) { | ||
| let _ = self.control.set(control.clone()); |
There was a problem hiding this comment.
SharedControl::set failures are silently ignored. If spawn is invoked more than once (multiple sessions, reconnects, or service restarts), this can hide unexpected state (e.g., control not matching assumptions). At minimum, handle the Err(value) case explicitly (log at warn!/debug!, or assert it’s expected) so operational issues aren’t silently swallowed.
| let _ = self.control.set(control.clone()); | |
| match self.control.set(control.clone()) { | |
| Ok(()) => {} | |
| Err(_) => { | |
| debug!( | |
| "GossipProtocolHandle::spawn called with control already initialized; \ | |
| ignoring new ServiceAsyncControl for session [{}], address: [{}], type: [{:?}]", | |
| context.id, context.address, context.ty | |
| ); | |
| } | |
| } |
There was a problem hiding this comment.
This is a pointless change. The protocol is set every time it's opened, but only the first time is successful; subsequent attempts result in errors. This can be ignored.
| myself.send_interval(network_maintenance_interval, || { | ||
| GossipActorMessage::TickNetworkMaintenance | ||
| }); |
There was a problem hiding this comment.
With control initialization moved from init() to spawn(), interval-driven behavior can now run before ServiceAsyncControl is available. Add a unit/integration test covering the “no connections yet” case (e.g., actor starts, ticks fire, and it does not panic / does not attempt network control usage until control is set).
| tentacle = { version = "0.7", default-features = false, features = [ | ||
| "upnp", | ||
| "parking_lot", | ||
| "unstable", | ||
| "openssl-vendored", | ||
| "tokio-runtime", | ||
| "tokio-timer", |
There was a problem hiding this comment.
Enabling Tentacle’s unstable feature can introduce semver-unstable APIs into downstream builds. If only a small part of the crate needs it, consider guarding spawn-based behavior behind a crate feature (or at least documenting in code/comments why unstable is required and what compatibility expectations are).
|
Some crates in Cargo.lock are downgraded without reason, please keep them unchanged or upgraded. |
This should be a downgrade by cargo itself; the hyper-util dependency is written very strangely: socket2 = { version = ">=0.5.9, <0.7", optional = true, features = ["all"] } A forced upgrade to socket2 restored the functionality. |
Currently, fiber does not rely on ServiceHandle's aggregation functionality, and forcibly aggregating it is not cost-effective. Using the Spawn feature might be better. The dependent init behavior has been changed to a once-in-a-time behavior, and the initialization time has been delayed from network startup to the first connection establishment.