Skip to content

feat: use tentacle spawn feature#1164

Open
driftluo wants to merge 2 commits intonervosnetwork:developfrom
driftluo:use-tentacle-spawn-feature
Open

feat: use tentacle spawn feature#1164
driftluo wants to merge 2 commits intonervosnetwork:developfrom
driftluo:use-tentacle-spawn-feature

Conversation

@driftluo
Copy link
Copy Markdown

@driftluo driftluo commented Mar 3, 2026

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.

@driftluo driftluo force-pushed the use-tentacle-spawn-feature branch 4 times, most recently from eb3fe7c to 4b312c1 Compare March 9, 2026 06:26
@driftluo driftluo force-pushed the use-tentacle-spawn-feature branch from 4b312c1 to dbb481d Compare March 9, 2026 09:19
@driftluo driftluo marked this pull request as ready for review March 9, 2026 09:52
@quake quake requested review from Copilot and jjyr March 9, 2026 22:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ServiceProtocol callbacks with ProtocolSpawn implementations that read from SubstreamReadPart.
  • Introduced SharedControl (Arc) to share ServiceAsyncControl across clones and initialize once.
  • Enabled Tentacle’s unstable feature 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.

Comment on lines 2002 to 2004
fn get_control(&self) -> &ServiceAsyncControl {
self.control.as_ref().expect("control exists")
self.control.get().expect("control exists")
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
control: &ServiceAsyncControl,
mut read_part: SubstreamReadPart,
) {
let _ = self.control.set(control.clone());
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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
);
}
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines 2543 to 2545
myself.send_interval(network_maintenance_interval, || {
GossipActorMessage::TickNetworkMaintenance
});
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment on lines 66 to 72
tentacle = { version = "0.7", default-features = false, features = [
"upnp",
"parking_lot",
"unstable",
"openssl-vendored",
"tokio-runtime",
"tokio-timer",
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
@jjyr
Copy link
Copy Markdown
Collaborator

jjyr commented Mar 10, 2026

Some crates in Cargo.lock are downgraded without reason, please keep them unchanged or upgraded.

 "socket2 0.6.2",
 "socket2 0.5.10",

@driftluo
Copy link
Copy Markdown
Author

driftluo commented Mar 10, 2026

Some crates in Cargo.lock are downgraded without reason, please keep them unchanged or upgraded.

 "socket2 0.6.2",
 "socket2 0.5.10",

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants