Skip to content

Commit 5eda65b

Browse files
committed
Stabilize mesh link admission rollout
1 parent a235d91 commit 5eda65b

2 files changed

Lines changed: 30 additions & 10 deletions

File tree

consul-postgres-ha/cluster-example/cluster.tf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ resource "phala_app_preflight" "worker" {
438438
name = "${var.cluster_name}-worker-${each.key}"
439439
size = "tdx.small"
440440
region = "US-WEST-1"
441-
kms = var.kms
442441
disk_size = 20
443442
storage_fs = "zfs"
444443
docker_compose = file("${path.module}/../compose/worker.yaml")

consul-postgres-ha/mesh-conn/main.go

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ func (m *Mesh) dialAndPump(parentCtx context.Context, peer Peer, sess *peerSessi
555555
sess.mu.Lock()
556556
sess.consumedAuth = [2]string{}
557557
sess.consumedAt = time.Time{}
558+
sess.linkUp = false
558559
sess.abortAttempt = abort
559560
sess.mu.Unlock()
560561
defer func() {
@@ -565,6 +566,7 @@ func (m *Mesh) dialAndPump(parentCtx context.Context, peer Peer, sess *peerSessi
565566
if sess.abortAttempt != nil {
566567
sess.abortAttempt = nil
567568
}
569+
sess.linkUp = false
568570
sess.mu.Unlock()
569571
}()
570572

@@ -694,6 +696,9 @@ func (m *Mesh) dialAndPump(parentCtx context.Context, peer Peer, sess *peerSessi
694696

695697
log.Printf("[%s] link up — peer vip=127.50.0.%d, allowlist=%v (udp=%d, tcp=%d)",
696698
peer.ID, peer.Vip, allowlistPorts(cfg.Allowlist), udpPortCount, len(tcpListeners))
699+
sess.mu.Lock()
700+
sess.linkUp = true
701+
sess.mu.Unlock()
697702
if m.onLinkUp != nil {
698703
m.onLinkUp(peer.ID)
699704
}
@@ -1057,10 +1062,27 @@ type peerSession struct {
10571062
agent *ice.Agent // replaced on every dialICE attempt; guarded by mu
10581063
consumedAuth [2]string // ufrag,pwd dialICE pulled off authCh; zero before
10591064
consumedAt time.Time // when consumedAuth was last set; zero before
1065+
linkUp bool // true after QUIC + forwarders are established
10601066
abortAttempt context.CancelFunc // non-nil for the duration of an attempt
10611067
candidateBuffer []ice.Candidate // remote candidates seen since last peer-auth; replayed into each new agent
10621068
}
10631069

1070+
const (
1071+
// pion transitions Checking -> Disconnected after this period without
1072+
// a viable selected pair. Disconnected is log-only for mesh-conn.
1073+
iceDisconnectedTimeout = 30 * time.Second
1074+
1075+
// pion transitions Disconnected -> Failed after this additional
1076+
// period. The ICE state callback aborts the attempt on Failed.
1077+
iceFailedTimeout = 60 * time.Second
1078+
1079+
// dialAttemptTimeout is only a guardrail for a stuck pion call path:
1080+
// it must be longer than pion's own failure budget so mesh-conn does
1081+
// not cancel a legitimate slow ICE attempt before the ICE state
1082+
// machine reaches Failed.
1083+
dialAttemptTimeout = iceDisconnectedTimeout + iceFailedTimeout + 15*time.Second
1084+
)
1085+
10641086
// supersedeGrace is the minimum time an attempt must have been
10651087
// running with consumedAuth set before pollLoop will supersede it on
10661088
// a fresh peer auth. Inside this window we trust the in-flight ICE
@@ -1157,10 +1179,6 @@ func (m *Mesh) dialICE(remoteID string, sess *peerSession, attemptCtx context.Co
11571179
// Disconnected stretch in the log timeline. We keep it at
11581180
// 30 s rather than 0 so the existing log signal is preserved
11591181
// if pion ever does have a sustained outage but recovers.
1160-
const (
1161-
iceDisconnectedTimeout = 30 * time.Second
1162-
iceFailedTimeout = 60 * time.Second
1163-
)
11641182
disconnectedTimeout := iceDisconnectedTimeout
11651183
failedTimeout := iceFailedTimeout
11661184
agentCfg := &ice.AgentConfig{
@@ -1282,10 +1300,10 @@ waitRemoteAuth:
12821300
m.onAttemptStarted(remoteID)
12831301
}
12841302

1285-
// 60s safety net; pion's default connectivity-check window is 30s
1286-
// so if Dial/Accept hasn't succeeded by then the state callback
1287-
// will have already fired abortAttempt.
1288-
dialTimer := time.AfterFunc(60*time.Second, func() {
1303+
// Safety net for a wedged Dial/Accept call path. This intentionally
1304+
// exceeds pion's Checking+Disconnected failure budget; ordinary
1305+
// failure is handled by the ICE Failed state callback above.
1306+
dialTimer := time.AfterFunc(dialAttemptTimeout, func() {
12891307
sess.mu.Lock()
12901308
if sess.abortAttempt != nil {
12911309
sess.abortAttempt()
@@ -1419,7 +1437,10 @@ func (m *Mesh) pollLoop(ctx context.Context) {
14191437
sess.mu.Lock()
14201438
sess.candidateBuffer = nil
14211439
zero := [2]string{}
1422-
if sess.abortAttempt != nil &&
1440+
if sess.linkUp {
1441+
log.Printf("[%s] fresh auth (ufrag=%s) queued for next attempt; current link is up",
1442+
msg.From, newAuth[0])
1443+
} else if sess.abortAttempt != nil &&
14231444
sess.consumedAuth != zero &&
14241445
sess.consumedAuth != newAuth {
14251446
elapsed := time.Since(sess.consumedAt)

0 commit comments

Comments
 (0)