refactor(platform): extract guild mesh peer mixin (Phase 741)

Move peer seen tracking, stale peer eviction, sweep timers, and adaptive
mesh retry delay into platform-guild-mesh-peer-mixin.js (67 manifest rows;
runtime registry 7 modules). Class ~33607 lines. No behavior change.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-03 11:02:43 -04:00
co-authored by Cursor
parent 8e53355fd5
commit e1aa68456c
5 changed files with 273 additions and 259 deletions
+2
View File
@@ -54,6 +54,8 @@ Application facade: one `PearcordPlatform` class that wires identity, database,
**Phase 723 (v0.8.699):** Dedicated slash registry & invoke audit export JSON — `slash-registry-json-mixin.js`, `slash-invoke-audit-json-mixin.js`, spans `slash-registry.json` / `slash-invoke-audit.json`, `getSlashInvokeAuditExportJsonExport`, `clearSlashInvokeAuditExportJsonExports`, deep links `openSlashRegistryJson` / `openSlashInvokeAuditJson`. Bundle: `npm run test:ci-phase723`. **Phase 723 (v0.8.699):** Dedicated slash registry & invoke audit export JSON — `slash-registry-json-mixin.js`, `slash-invoke-audit-json-mixin.js`, spans `slash-registry.json` / `slash-invoke-audit.json`, `getSlashInvokeAuditExportJsonExport`, `clearSlashInvokeAuditExportJsonExports`, deep links `openSlashRegistryJson` / `openSlashInvokeAuditJson`. Bundle: `npm run test:ci-phase723`.
**Phase 741 (v0.8.717):** `platform-guild-mesh-peer-mixin.js` (67 mixin rows); stale peer evict + retry delay helpers extracted. Bundle: `npm run test:ci-phase741`.
**Phase 740 (v0.8.716):** `platform-guild-mesh-bounded-mixin.js`, `platform-federation-view-mixin.js` (66 mixin rows). Bundle: `npm run test:ci-phase740`. **Phase 740 (v0.8.716):** `platform-guild-mesh-bounded-mixin.js`, `platform-federation-view-mixin.js` (66 mixin rows). Bundle: `npm run test:ci-phase740`.
**Phase 739 (v0.8.715):** `platform-guild-open-fallback-mixin.js`, `platform-partition-heal-state-mixin.js` (64 mixin rows); `platform-runtime-mixin-registry.js`. Bundle: `npm run test:ci-phase739`. **Phase 739 (v0.8.715):** `platform-guild-open-fallback-mixin.js`, `platform-partition-heal-state-mixin.js` (64 mixin rows); `platform-runtime-mixin-registry.js`. Bundle: `npm run test:ci-phase739`.
+267
View File
@@ -0,0 +1,267 @@
'use strict'
const localScope = require('./platform-index-local-imports')
const swarmScope = require('./platform-swarm-manager-imports')
const platformGuildMeshPeerMixin = {
_guildMeshPeerSeenMap (guildId) {
const gid = guildId || this.guild?.guild?.id
if (!gid) return null
let map = this._guildMeshPeerSeenByGuild.get(gid)
if (!map) {
map = new Map()
this._guildMeshPeerSeenByGuild.set(gid, map)
}
return map
},
_touchGuildMeshPeerSeen (guildId, peerId, source = 'activity', opts = {}) {
const gid = guildId || this.guild?.guild?.id
if (!gid || !peerId) return null
const map = this._guildMeshPeerSeenMap(gid)
const now = Date.now()
const prev = map.get(peerId) || { peerId, joinedAt: now, lastSeenAt: 0, dropCount: 0 }
const sparseCursors = this._sparseAckCursorByGuild.get(gid) || {}
const hasSparse = Object.keys(sparseCursors).length > 0
const row = {
...prev,
peerId,
joinedAt: prev.joinedAt || now,
lastSeenAt: now,
lastSource: source,
rttMs:
Number(opts.rttMs) ||
Number(prev.rttMs) ||
Number(this._lastGuildMeshWireRttMs) ||
Number(process.env.PEARCORD_GUILD_MESH_RTT_MS) ||
120,
dropCount: Number(prev.dropCount) || 0,
sparseCursorStale:
hasSparse &&
Object.values(sparseCursors).some((off) => Number(off) > 0) &&
now - (Number(prev.lastSeenAt) || now) > 45000
}
row.qualityScore = localScope.computeMeshPeerQualityScore(row, {
fallbackRttMs: this._lastGuildMeshWireRttMs
})
map.set(peerId, row)
const health = this._guildSyncHealthByGuild.get(gid)
const lastPeerSeenAt = Math.max(Number(health?.lastPeerSeenAt) || 0, now)
this._patchGuildSyncHealth({
guildId: gid,
lastPeerSeenAt,
lastSuccessfulPeerContactAt: lastPeerSeenAt
})
return row
},
_touchAllGuildMeshPeersSeen (guildId, source = 'mesh-activity') {
const gid = guildId || this.guild?.guild?.id
if (!gid || !this.guild?.peers?.size) return 0
let n = 0
for (const peerId of this.guild.peers.keys()) {
this._touchGuildMeshPeerSeen(gid, peerId, source)
n++
}
return n
},
_forgetGuildMeshPeerSeen (guildId, peerId) {
const gid = guildId || this.guild?.guild?.id
if (!gid || !peerId) return
this._guildMeshPeerSeenByGuild.get(gid)?.delete(peerId)
},
_getGuildMeshPeerRetryAttempt (guildId) {
const gid = guildId || this.guild?.guild?.id
if (!gid) return 0
const meta = this._guildMeshPeerRetryMetaByGuild.get(gid)
if (this.guild?.guild?.id === gid) {
return Math.max(
Number(meta?.attempt) || 0,
Number(this._guildMeshPeerRetryAttempts) || 0
)
}
return Number(meta?.attempt) || 0
},
/**
* Drop hyperswarm sockets that stayed connected without mesh activity.
* @returns {{ evicted: number, peerRetryAttempt: number, lastPeerSeenAt: number }}
*/
_evictStaleGuildMeshPeers (guildId, opts = {}) {
const gid = guildId || this.guild?.guild?.id
const out = { evicted: 0, peerRetryAttempt: 0, lastPeerSeenAt: 0 }
if (!gid || this.guild?.guild?.id !== gid || !this.guild?.peers?.size) {
return out
}
const staleMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_STALE_MS) || 180000
const minAgeMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_STALE_MIN_AGE_MS) || 45000
const now = Date.now()
const peerMap = this._guildMeshPeerSeenMap(gid)
const peerRetryAttempt = this._getGuildMeshPeerRetryAttempt(gid)
out.peerRetryAttempt = peerRetryAttempt
for (const [peerId, conn] of [...this.guild.peers.entries()]) {
const row = peerMap.get(peerId) || {
peerId,
joinedAt: now,
lastSeenAt: 0
}
const joinedAt = Number(row.joinedAt) || now
const lastSeenAt = Number(row.lastSeenAt) || 0
const connAgeMs = now - joinedAt
const idleMs = lastSeenAt ? now - lastSeenAt : connAgeMs
const idleThreshold = opts.force === true ? minAgeMs : staleMs
const stale = connAgeMs >= minAgeMs && idleMs >= idleThreshold
if (!stale) continue
try {
conn.destroy?.()
} catch {
// ignore
}
row.dropCount = (Number(row.dropCount) || 0) + 1
this.guild.peers.delete(peerId)
this.guild._channels?.delete(peerId)
this.guild._attachChannels?.delete(peerId)
this.guild._voiceChannels?.delete(peerId)
this.guild._screenChannels?.delete(peerId)
peerMap.delete(peerId)
this._trackGuildTopicPeer(gid, peerId, 'leave')
out.evicted += 1
this.log.info('guild mesh stale peer evicted', {
spanKind: 'guild.mesh.stale-peer-evict',
guildId: gid,
peerId,
peerRetryAttempt,
lastPeerSeenAt: lastSeenAt || 0,
idleMs,
connAgeMs,
source: opts.source || 'stale-sweep'
})
}
if (out.evicted > 0) {
const total =
(this._guildMeshStalePeerEvictedTotalByGuild.get(gid) || 0) + out.evicted
this._guildMeshStalePeerEvictedTotalByGuild.set(gid, total)
const health = this._guildSyncHealthByGuild.get(gid)
out.lastPeerSeenAt = Number(health?.lastPeerSeenAt) || 0
let maxSeen = 0
for (const row of peerMap.values()) {
maxSeen = Math.max(maxSeen, Number(row.lastSeenAt) || 0)
}
const peers = this.guild.peers?.size ?? 0
this._patchGuildSyncHealth({
guildId: gid,
peers,
peerRetryAttempt,
lastPeerSeenAt: maxSeen || out.lastPeerSeenAt,
stalePeersEvictedLast: out.evicted,
lastStalePeerEvictAt: now
})
this._logMeshChurn('stale-peer-evict', {
guildId: gid,
evicted: out.evicted,
peerRetryAttempt,
lastPeerSeenAt: maxSeen || out.lastPeerSeenAt,
meshPeerCount: peers
})
if (peers === 0) this._scheduleGuildMeshPeerRetry(gid)
}
return out
},
_maybeEvictStaleGuildMeshPeers (guildId, source = 'sweep') {
if (!guildId || this.guild?.guild?.id !== guildId) return { evicted: 0 }
if (!(this.guild?.peers?.size ?? 0)) return { evicted: 0 }
return this._evictStaleGuildMeshPeers(guildId, { source })
},
_stopGuildMeshStalePeerSweep () {
if (this._guildMeshStalePeerSweepTimer) {
clearInterval(this._guildMeshStalePeerSweepTimer)
this._guildMeshStalePeerSweepTimer = null
}
},
_startGuildMeshStalePeerSweep (guildId) {
this._stopGuildMeshStalePeerSweep()
const gid = guildId || this.guild?.guild?.id
if (!gid) return
const intervalMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_SWEEP_MS) || 60000
this._guildMeshStalePeerSweepTimer = setInterval(() => {
if (this.guild?.guild?.id !== gid) {
this._stopGuildMeshStalePeerSweep()
return
}
this._maybeEvictStaleGuildMeshPeers(gid, 'interval-sweep')
}, intervalMs)
if (typeof this._guildMeshStalePeerSweepTimer.unref === 'function') {
this._guildMeshStalePeerSweepTimer.unref()
}
},
/**
* Mesh peer retry delay from time since last successful peer contact (not fixed attempt cadence).
* @param {string} guildId
* @param {number} attempt 1-based retry attempt
*/
_computeGuildMeshPeerRetryDelayMs (guildId, attempt = 1) {
const meshRtt =
Number(this._lastGuildMeshWireRttMs) ||
Number(process.env.PEARCORD_GUILD_MESH_RTT_MS) ||
120
const attemptIdx = Math.max(0, Number(attempt) - 1)
let baseMs = 3000
try {
const scaled = swarmScope.adaptiveBurstDelays(meshRtt, [2800, 5000, 8000, 12000, 15000, 18000])
baseMs = scaled[Math.min(attemptIdx, scaled.length - 1)] || 3000
} catch {
const retryDelays = [3000, 5000, 8000, 12000, 15000]
baseMs = retryDelays[Math.min(attemptIdx, retryDelays.length - 1)] || 3000
}
const health = this._guildSyncHealthByGuild.get(guildId)
const lastContact = Math.max(
Number(health?.lastPeerSeenAt) || 0,
Number(health?.lastSuccessfulPeerContactAt) || 0
)
const now = Date.now()
const minMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_RETRY_MIN_MS) || 1500
const maxMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_RETRY_MAX_MS) || 60000
if (!lastContact) {
return Math.min(maxMs, Math.round(baseMs * (attempt <= 2 ? 1.15 : 1.3)))
}
const sinceContactMs = Math.max(0, now - lastContact)
let delayMs = baseMs
if (sinceContactMs < 30000) {
delayMs = Math.max(minMs, Math.round(minMs + sinceContactMs * 0.08))
} else if (sinceContactMs < 180000) {
delayMs = Math.max(baseMs, Math.round(baseMs + sinceContactMs * 0.12))
} else {
const extra = Math.min(30000, Math.round((sinceContactMs - 180000) * 0.06))
delayMs = Math.min(maxMs, Math.round(baseMs * 1.2 + extra))
}
const jitter = localScope.meshRejoinJitterMs(guildId, `retry-${attempt}`)
const out = Math.min(maxMs, Math.max(minMs, delayMs + jitter))
this.log.debug('guild.mesh.retry.adaptive', {
spanKind: 'guild.mesh.retry.adaptive',
guildId,
attempt,
meshRtt,
sinceContactMs: lastContact ? now - lastContact : null,
baseMs,
delayMs: out,
spacingSource: lastContact ? 'last-peer-contact' : 'cold-start'
})
return out
}
}
module.exports = { platformGuildMeshPeerMixin }
+2 -1
View File
@@ -4,7 +4,7 @@
* Ordered PearcordPlatform prototype mixin registration (Phase 730). * Ordered PearcordPlatform prototype mixin registration (Phase 730).
* Preserves assign order from index.js / apply-platform-mixins (Phase 727). * Preserves assign order from index.js / apply-platform-mixins (Phase 727).
*/ */
const PLATFORM_MIXIN_ASSIGNMENT_COUNT = 66 const PLATFORM_MIXIN_ASSIGNMENT_COUNT = 67
const PLATFORM_MIXIN_ASSIGNMENTS = [ const PLATFORM_MIXIN_ASSIGNMENTS = [
{ module: './polls-scheduling', export: 'pollSchedulingMixin' }, { module: './polls-scheduling', export: 'pollSchedulingMixin' },
@@ -72,6 +72,7 @@ const PLATFORM_MIXIN_ASSIGNMENTS = [
{ module: './platform-partition-heal-state-mixin', export: 'platformPartitionHealStateMixin' }, { module: './platform-partition-heal-state-mixin', export: 'platformPartitionHealStateMixin' },
{ module: './platform-guild-mesh-bounded-mixin', export: 'platformGuildMeshBoundedMixin' }, { module: './platform-guild-mesh-bounded-mixin', export: 'platformGuildMeshBoundedMixin' },
{ module: './platform-federation-view-mixin', export: 'platformFederationViewMixin' }, { module: './platform-federation-view-mixin', export: 'platformFederationViewMixin' },
{ module: './platform-guild-mesh-peer-mixin', export: 'platformGuildMeshPeerMixin' },
{ module: './platform-diagnostics-mixin', export: 'platformDiagnosticsMixin' } { module: './platform-diagnostics-mixin', export: 'platformDiagnosticsMixin' }
] ]
-257
View File
@@ -273,263 +273,6 @@ class PearcordPlatform extends EventEmitter {
this._forumTagFilters = [] this._forumTagFilters = []
} }
_guildMeshPeerSeenMap (guildId) {
const gid = guildId || this.guild?.guild?.id
if (!gid) return null
let map = this._guildMeshPeerSeenByGuild.get(gid)
if (!map) {
map = new Map()
this._guildMeshPeerSeenByGuild.set(gid, map)
}
return map
}
_touchGuildMeshPeerSeen (guildId, peerId, source = 'activity', opts = {}) {
const gid = guildId || this.guild?.guild?.id
if (!gid || !peerId) return null
const map = this._guildMeshPeerSeenMap(gid)
const now = Date.now()
const prev = map.get(peerId) || { peerId, joinedAt: now, lastSeenAt: 0, dropCount: 0 }
const sparseCursors = this._sparseAckCursorByGuild.get(gid) || {}
const hasSparse = Object.keys(sparseCursors).length > 0
const row = {
...prev,
peerId,
joinedAt: prev.joinedAt || now,
lastSeenAt: now,
lastSource: source,
rttMs:
Number(opts.rttMs) ||
Number(prev.rttMs) ||
Number(this._lastGuildMeshWireRttMs) ||
Number(process.env.PEARCORD_GUILD_MESH_RTT_MS) ||
120,
dropCount: Number(prev.dropCount) || 0,
sparseCursorStale:
hasSparse &&
Object.values(sparseCursors).some((off) => Number(off) > 0) &&
now - (Number(prev.lastSeenAt) || now) > 45000
}
row.qualityScore = localScope.computeMeshPeerQualityScore(row, {
fallbackRttMs: this._lastGuildMeshWireRttMs
})
map.set(peerId, row)
const health = this._guildSyncHealthByGuild.get(gid)
const lastPeerSeenAt = Math.max(Number(health?.lastPeerSeenAt) || 0, now)
this._patchGuildSyncHealth({
guildId: gid,
lastPeerSeenAt,
lastSuccessfulPeerContactAt: lastPeerSeenAt
})
return row
}
_touchAllGuildMeshPeersSeen (guildId, source = 'mesh-activity') {
const gid = guildId || this.guild?.guild?.id
if (!gid || !this.guild?.peers?.size) return 0
let n = 0
for (const peerId of this.guild.peers.keys()) {
this._touchGuildMeshPeerSeen(gid, peerId, source)
n++
}
return n
}
_forgetGuildMeshPeerSeen (guildId, peerId) {
const gid = guildId || this.guild?.guild?.id
if (!gid || !peerId) return
this._guildMeshPeerSeenByGuild.get(gid)?.delete(peerId)
}
_getGuildMeshPeerRetryAttempt (guildId) {
const gid = guildId || this.guild?.guild?.id
if (!gid) return 0
const meta = this._guildMeshPeerRetryMetaByGuild.get(gid)
if (this.guild?.guild?.id === gid) {
return Math.max(
Number(meta?.attempt) || 0,
Number(this._guildMeshPeerRetryAttempts) || 0
)
}
return Number(meta?.attempt) || 0
}
/**
* Drop hyperswarm sockets that stayed connected without mesh activity.
* @returns {{ evicted: number, peerRetryAttempt: number, lastPeerSeenAt: number }}
*/
_evictStaleGuildMeshPeers (guildId, opts = {}) {
const gid = guildId || this.guild?.guild?.id
const out = { evicted: 0, peerRetryAttempt: 0, lastPeerSeenAt: 0 }
if (!gid || this.guild?.guild?.id !== gid || !this.guild?.peers?.size) {
return out
}
const staleMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_STALE_MS) || 180000
const minAgeMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_STALE_MIN_AGE_MS) || 45000
const now = Date.now()
const peerMap = this._guildMeshPeerSeenMap(gid)
const peerRetryAttempt = this._getGuildMeshPeerRetryAttempt(gid)
out.peerRetryAttempt = peerRetryAttempt
for (const [peerId, conn] of [...this.guild.peers.entries()]) {
const row = peerMap.get(peerId) || {
peerId,
joinedAt: now,
lastSeenAt: 0
}
const joinedAt = Number(row.joinedAt) || now
const lastSeenAt = Number(row.lastSeenAt) || 0
const connAgeMs = now - joinedAt
const idleMs = lastSeenAt ? now - lastSeenAt : connAgeMs
const idleThreshold = opts.force === true ? minAgeMs : staleMs
const stale = connAgeMs >= minAgeMs && idleMs >= idleThreshold
if (!stale) continue
try {
conn.destroy?.()
} catch {
// ignore
}
row.dropCount = (Number(row.dropCount) || 0) + 1
this.guild.peers.delete(peerId)
this.guild._channels?.delete(peerId)
this.guild._attachChannels?.delete(peerId)
this.guild._voiceChannels?.delete(peerId)
this.guild._screenChannels?.delete(peerId)
peerMap.delete(peerId)
this._trackGuildTopicPeer(gid, peerId, 'leave')
out.evicted += 1
this.log.info('guild mesh stale peer evicted', {
spanKind: 'guild.mesh.stale-peer-evict',
guildId: gid,
peerId,
peerRetryAttempt,
lastPeerSeenAt: lastSeenAt || 0,
idleMs,
connAgeMs,
source: opts.source || 'stale-sweep'
})
}
if (out.evicted > 0) {
const total =
(this._guildMeshStalePeerEvictedTotalByGuild.get(gid) || 0) + out.evicted
this._guildMeshStalePeerEvictedTotalByGuild.set(gid, total)
const health = this._guildSyncHealthByGuild.get(gid)
out.lastPeerSeenAt = Number(health?.lastPeerSeenAt) || 0
let maxSeen = 0
for (const row of peerMap.values()) {
maxSeen = Math.max(maxSeen, Number(row.lastSeenAt) || 0)
}
const peers = this.guild.peers?.size ?? 0
this._patchGuildSyncHealth({
guildId: gid,
peers,
peerRetryAttempt,
lastPeerSeenAt: maxSeen || out.lastPeerSeenAt,
stalePeersEvictedLast: out.evicted,
lastStalePeerEvictAt: now
})
this._logMeshChurn('stale-peer-evict', {
guildId: gid,
evicted: out.evicted,
peerRetryAttempt,
lastPeerSeenAt: maxSeen || out.lastPeerSeenAt,
meshPeerCount: peers
})
if (peers === 0) this._scheduleGuildMeshPeerRetry(gid)
}
return out
}
_maybeEvictStaleGuildMeshPeers (guildId, source = 'sweep') {
if (!guildId || this.guild?.guild?.id !== guildId) return { evicted: 0 }
if (!(this.guild?.peers?.size ?? 0)) return { evicted: 0 }
return this._evictStaleGuildMeshPeers(guildId, { source })
}
_stopGuildMeshStalePeerSweep () {
if (this._guildMeshStalePeerSweepTimer) {
clearInterval(this._guildMeshStalePeerSweepTimer)
this._guildMeshStalePeerSweepTimer = null
}
}
_startGuildMeshStalePeerSweep (guildId) {
this._stopGuildMeshStalePeerSweep()
const gid = guildId || this.guild?.guild?.id
if (!gid) return
const intervalMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_SWEEP_MS) || 60000
this._guildMeshStalePeerSweepTimer = setInterval(() => {
if (this.guild?.guild?.id !== gid) {
this._stopGuildMeshStalePeerSweep()
return
}
this._maybeEvictStaleGuildMeshPeers(gid, 'interval-sweep')
}, intervalMs)
if (typeof this._guildMeshStalePeerSweepTimer.unref === 'function') {
this._guildMeshStalePeerSweepTimer.unref()
}
}
/**
* Mesh peer retry delay from time since last successful peer contact (not fixed attempt cadence).
* @param {string} guildId
* @param {number} attempt 1-based retry attempt
*/
_computeGuildMeshPeerRetryDelayMs (guildId, attempt = 1) {
const meshRtt =
Number(this._lastGuildMeshWireRttMs) ||
Number(process.env.PEARCORD_GUILD_MESH_RTT_MS) ||
120
const attemptIdx = Math.max(0, Number(attempt) - 1)
let baseMs = 3000
try {
const scaled = swarmScope.adaptiveBurstDelays(meshRtt, [2800, 5000, 8000, 12000, 15000, 18000])
baseMs = scaled[Math.min(attemptIdx, scaled.length - 1)] || 3000
} catch {
const retryDelays = [3000, 5000, 8000, 12000, 15000]
baseMs = retryDelays[Math.min(attemptIdx, retryDelays.length - 1)] || 3000
}
const health = this._guildSyncHealthByGuild.get(guildId)
const lastContact = Math.max(
Number(health?.lastPeerSeenAt) || 0,
Number(health?.lastSuccessfulPeerContactAt) || 0
)
const now = Date.now()
const minMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_RETRY_MIN_MS) || 1500
const maxMs = Number(process.env.PEARCORD_GUILD_MESH_PEER_RETRY_MAX_MS) || 60000
if (!lastContact) {
return Math.min(maxMs, Math.round(baseMs * (attempt <= 2 ? 1.15 : 1.3)))
}
const sinceContactMs = Math.max(0, now - lastContact)
let delayMs = baseMs
if (sinceContactMs < 30000) {
delayMs = Math.max(minMs, Math.round(minMs + sinceContactMs * 0.08))
} else if (sinceContactMs < 180000) {
delayMs = Math.max(baseMs, Math.round(baseMs + sinceContactMs * 0.12))
} else {
const extra = Math.min(30000, Math.round((sinceContactMs - 180000) * 0.06))
delayMs = Math.min(maxMs, Math.round(baseMs * 1.2 + extra))
}
const jitter = localScope.meshRejoinJitterMs(guildId, `retry-${attempt}`)
const out = Math.min(maxMs, Math.max(minMs, delayMs + jitter))
this.log.debug('guild.mesh.retry.adaptive', {
spanKind: 'guild.mesh.retry.adaptive',
guildId,
attempt,
meshRtt,
sinceContactMs: lastContact ? now - lastContact : null,
baseMs,
delayMs: out,
spacingSource: lastContact ? 'last-peer-contact' : 'cold-start'
})
return out
}
_refreshGuildTopicPoolCap (guildId) { _refreshGuildTopicPoolCap (guildId) {
const gid = guildId || this.guild?.guild?.id const gid = guildId || this.guild?.guild?.id
if (!gid || !this._guildTopicPool) return null if (!gid || !this._guildTopicPool) return null
+2 -1
View File
@@ -7,7 +7,8 @@ const PLATFORM_RUNTIME_MIXIN_MODULES = [
'./platform-guild-open-fallback-mixin', './platform-guild-open-fallback-mixin',
'./platform-partition-heal-state-mixin', './platform-partition-heal-state-mixin',
'./platform-guild-mesh-bounded-mixin', './platform-guild-mesh-bounded-mixin',
'./platform-federation-view-mixin' './platform-federation-view-mixin',
'./platform-guild-mesh-peer-mixin'
] ]
const PLATFORM_RUNTIME_MIXIN_COUNT = PLATFORM_RUNTIME_MIXIN_MODULES.length const PLATFORM_RUNTIME_MIXIN_COUNT = PLATFORM_RUNTIME_MIXIN_MODULES.length