Post

Icon 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

StepMutex ProtectionPurpose
Beacon receivedBeaconService.wireProcessingMutexPrevent concurrent wire handling
Wire processingHostProcessor.wireProcessingMutexSerialize decision logic
Session checkPeerSessionManager.mutexSafe map access
Session updatePeerSessionManager.mutexSafe map modification
Node updateNodeManager.nodesMutexSafe 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:

  1. Check: Is new beacon being sent? (Server should auto-broadcast)
  2. Check: Is client receiving wire? (Should log β€œreceived wire: Server from {id}”)
  3. Check: Is session check working? (Should log β€œknown session: false”)
  4. Check: Is trustServer() being called? (Should log β€œRe-establishing connection”)
  5. Check: Are there any exceptions? (Check error logs)

If getting duplicate connection attempts:

  1. Check: BeaconService jobs map size (should be 1 per node.id)
  2. Check: Is session being properly updated? (Old session should be overwritten)
  3. Check: Are duplicate beacons hitting the β€œknown session: true” path?

If session state corruption:

  1. Check: All PeerSessionManager calls are suspend and use mutex
  2. Check: No direct access to knownSessions map outside of mutex
  3. 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.