HostProcessor Connection Logic
HostProcessor Connection Logic
HostProcessor Connection Logic
HostProcessor Connection Logic - Quick Reference
π― Decision Tree: Wire Processing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Incoming Wire from Beacon
ββ wire.id == installId? β SKIP (it's me)
ββ wire.type == Server or Client?
β β
β ββ NodeManager has wire.id?
β β β
β β ββ NO (New Peer) βββββββββββββββββββββββββ
β β β β
β β ββ YES (Known Peer) β
β β β β
β β ββ Session known? β
β β β β β
β β β ββ NO β NEW SESSION βββββββββ β
β β β β β β
β β β ββ YES β DUPLICATE βββββββ β β
β β β β β
β β βΌ βΌ βΌ
β β [Duplicate] [Reconnect] [New Peer]
β β
β ββ Process accordingly
β
ββ Other type β LOG WARNING
π Scenarios & Actions
Scenario 1: New Peer Discovered
Condition: NodeManager returns NodeFlow.Error (doesnβt have this node ID)
Actions:
1
2
3
4
5
6
1. peerSessionManager.add(wire.id, wire.sessionId)
2. nodeManager.update(wire.toNode()) // Create stub
3. If wire.type == Server:
ββ serverHandshakeProcess.trustServer(wire)
4. If wire.type == Client:
ββ beaconManager.sendSignal(node) // Advertise back
Example:
- Client starts for first time β Server discovers it β Server advertises back
Scenario 2: Known Peer, New Session (RESTART)
Condition: NodeManager has node, but session is NEW
Actions:
1
2
3
4
5
6
7
8
1. peerSessionManager.add(wire.id, wire.sessionId) // Update session
2. nodeManager.update(wire.toNode()) // Update metadata
3. If wire.type == Server:
ββ serverHandshakeProcess.trustServer(wire) // Re-establish
ββ If I'm also Server:
ββ beaconManager.sendSignal(node) // Advertise back
4. If wire.type == Client:
ββ beaconManager.sendSignal(node) // Advertise
Example:
- Server crashes and restarts β Client receives new sessionId β Client re-establishes connection
Scenario 3: Known Peer, Same Session (DUPLICATE)
Condition: NodeManager has node AND session is KNOWN
Actions:
1
2
1. nodeManager.update(wire.toNode()) // Update metadata only
2. NO re-establishment (prevent loops)
Example:
- Server sends multiple beacons β Client ignores after first
π Session Lifecycle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Server Starts
β
Generates sessionId = UUID
β
Broadcasts beacon with sessionId
β
Client receives
β
peerSessionManager.add(serverId, sessionId)
β
[Server Running] β Periodic beacons β [Client knows session]
β
Server Crashes
β
Client still has old sessionId in memory
β
Server Restarts
β
Generates NEW sessionId = UUID
β
Broadcasts beacon with NEW sessionId
β
Client receives
β
isKnownSession(new sessionId) = FALSE
β
Client detects RECONNECTION scenario
β
peerSessionManager.add(serverId, NEW sessionId) // Overwrites old
β
Re-establish connection (trustServer, etc.)
π¦ Thread Safety Checkpoints
| Step | Mutex Protection | Purpose |
|---|---|---|
| Beacon received | BeaconService.wireProcessingMutex | Prevent concurrent wire handling |
| Wire processing | HostProcessor.wireProcessingMutex | Serialize decision logic |
| Session check | PeerSessionManager.mutex | Safe map access |
| Session update | PeerSessionManager.mutex | Safe map modification |
| Node update | NodeManager.nodesMutex | Safe node map access |
π― Type-Specific Logic
If Wire Type = Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
when {
new peer -> {
trustServer(wire) // Download certs, nodes, open WebSocket
}
known peer, new session -> {
trustServer(wire) // RE-download everything
if (I'm also a server) {
sendSignal(node) // Server-to-server discovery
}
}
known peer, same session -> {
update(wire.toNode()) // Metadata only
}
}
If Wire Type = Client
1
2
3
4
5
6
7
8
9
10
11
when {
new peer -> {
sendSignal(node) // Advertise myself to new client
}
known peer, new session -> {
sendSignal(node) // Re-advertise (client restarted)
}
known peer, same session -> {
update(wire.toNode()) // Metadata only
}
}
π Debugging Checklist
If client doesnβt reconnect after server restart:
- Check: Is new beacon being sent? (Server should auto-broadcast)
- Check: Is client receiving wire? (Should log βreceived wire: Server from {id}β)
- Check: Is session check working? (Should log βknown session: falseβ)
- Check: Is trustServer() being called? (Should log βRe-establishing connectionβ)
- Check: Are there any exceptions? (Check error logs)
If getting duplicate connection attempts:
- Check: BeaconService jobs map size (should be 1 per node.id)
- Check: Is session being properly updated? (Old session should be overwritten)
- Check: Are duplicate beacons hitting the βknown session: trueβ path?
If session state corruption:
- Check: All PeerSessionManager calls are suspend and use mutex
- Check: No direct access to knownSessions map outside of mutex
- Verify: LazyThreadSafetyMode.SYNCHRONIZED on all by inject()
π Expected Log Sequence
New Client Connects to Server
Server logs:
1
2
3
4
5
[INFO] emit: Client
[INFO] Starting beacon service for node {client-id}
[INFO] received wire: Client from {client-id}
[INFO] Discovered new Client. known session: false
[INFO] Beacon service started and initial signal sent
Client logs:
1
2
3
4
[INFO] emit: Server
[INFO] received wire: Server from {server-id}
[INFO] Discovered new Server. known session: false
[INFO] Re-establishing connection to server
Server Restarts (Client Already Running)
Server logs:
1
2
3
[INFO] emit: Server
[INFO] Starting beacon service for node {server-id}
[INFO] Beacon service started and initial signal sent
Client logs:
1
2
3
4
[INFO] received wire: Server from {server-id}
[INFO] Received wire from known Server. known session: false
[INFO] Known Server with NEW session - handling reconnection
[INFO] Re-establishing connection to restarted server {server-id}
This post is licensed under CC BY 4.0 by the author.