feat(v0.8.689): rename all export CSV identifiers to JSON-only naming

Complete sweep of filenames, symbols, IPC channels, storage keys, CSS classes,
smoke scripts, and docs. Payloads remain signed JSON envelopes (Phase 713).
This commit is contained in:
Raven Scott
2026-06-03 05:54:25 -04:00
parent b08d346fcd
commit e898912942
25 changed files with 3057 additions and 2940 deletions
+23 -23
View File
@@ -2,49 +2,49 @@
Application facade: one `PearcordPlatform` class that wires identity, database, guild mesh, DMs, invites, voice, discovery, bots, and dozens of feature modules for the Pearcord desktop sidecar and companion.
**Phase 711 (v0.8.686):** Activity invite CSV & profile banner export — `activity-csv-mixin.js`, `activity.csv` spans (`guildActivityCsvCount`), `pushActivityInviteCsvToMesh`, `pushProfileBannerExportToMesh`, deep link `openActivityCsv`. Bundle: `npm run test:ci-phase711`.
**Phase 711 (v0.8.686):** Activity invite JSON & profile banner export — `activity-json-mixin.js`, `activity.json` spans (`guildActivityJsonCount`), `pushActivityInviteJsonToMesh`, `pushProfileBannerExportToMesh`, deep link `openActivityJson`. Bundle: `npm run test:ci-phase711`.
**Phase 710 (v0.8.685):** Custom status CSV & guild widget export — `status-csv-mixin.js`, `status.csv` spans (`guildStatusCsvCount`), `pushCustomStatusCsvToMesh`, `pushGuildWidgetExportToMesh`, deep link `openStatusCsv`. Bundle: `npm run test:ci-phase710`.
**Phase 710 (v0.8.685):** Custom status JSON & guild widget export — `status-json-mixin.js`, `status.json` spans (`guildStatusJsonCount`), `pushCustomStatusJsonToMesh`, `pushGuildWidgetExportToMesh`, deep link `openStatusJson`. Bundle: `npm run test:ci-phase710`.
**Phase 709 (v0.8.684):** Notification override CSV & channel follow export — `notification-csv-mixin.js`, `notification.csv` spans (`guildNotificationCsvCount`), `pushNotificationOverrideCsvToMesh`, `pushChannelFollowExportToMesh`, deep link `openNotificationCsv`. Bundle: `npm run test:ci-phase709`.
**Phase 709 (v0.8.684):** Notification override JSON & channel follow export — `notification-json-mixin.js`, `notification.json` spans (`guildNotificationJsonCount`), `pushNotificationOverrideJsonToMesh`, `pushChannelFollowExportToMesh`, deep link `openNotificationJson`. Bundle: `npm run test:ci-phase709`.
**Phase 708 (v0.8.683):** Presence activity CSV & read-state export — `presence-csv-mixin.js`, `presence.csv` spans (`guildPresenceCsvCount`), `pushPresenceActivityCsvToMesh`, `pushReadStateExportToMesh`, deep link `openPresenceCsv`. Bundle: `npm run test:ci-phase708`.
**Phase 708 (v0.8.683):** Presence activity JSON & read-state export — `presence-json-mixin.js`, `presence.json` spans (`guildPresenceJsonCount`), `pushPresenceActivityJsonToMesh`, `pushReadStateExportToMesh`, deep link `openPresenceJson`. Bundle: `npm run test:ci-phase708`.
**Phase 707 (v0.8.682):** Screen share CSV & soundboard registry export — `screen-csv-mixin.js`, `screen.csv` spans (`guildScreenCsvCount`), `pushScreenShareCsvToMesh`, `pushSoundboardRegistryExportToMesh`, deep link `openScreenCsv`. Bundle: `npm run test:ci-phase707`.
**Phase 707 (v0.8.682):** Screen share JSON & soundboard registry export — `screen-json-mixin.js`, `screen.json` spans (`guildScreenJsonCount`), `pushScreenShareJsonToMesh`, `pushSoundboardRegistryExportToMesh`, deep link `openScreenJson`. Bundle: `npm run test:ci-phase707`.
**Phase 706 (v0.8.681):** Voice state CSV & boost ledger export — `voice-csv-mixin.js`, `voice.csv` spans (`guildVoiceCsvCount`), `pushVoiceStateCsvToMesh`, `pushBoostLedgerExportToMesh`, deep link `openVoiceCsv`. Bundle: `npm run test:ci-phase706`.
**Phase 706 (v0.8.681):** Voice state JSON & boost ledger export — `voice-json-mixin.js`, `voice.json` spans (`guildVoiceJsonCount`), `pushVoiceStateJsonToMesh`, `pushBoostLedgerExportToMesh`, deep link `openVoiceJson`. Bundle: `npm run test:ci-phase706`.
**Phase 705 (v0.8.680):** Stage instance CSV & guild event export — `stage-csv-mixin.js`, `stage.csv` spans (`guildStageCsvCount`), `pushStageInstanceCsvToMesh`, `pushGuildEventExportToMesh`, deep link `openStageCsv`. Bundle: `npm run test:ci-phase705`.
**Phase 705 (v0.8.680):** Stage instance JSON & guild event export — `stage-json-mixin.js`, `stage.json` spans (`guildStageJsonCount`), `pushStageInstanceJsonToMesh`, `pushGuildEventExportToMesh`, deep link `openStageJson`. Bundle: `npm run test:ci-phase705`.
**Phase 704 (v0.8.679):** Thread archive CSV & forum tag export — `thread-csv-mixin.js`, `thread.csv` spans (`guildThreadCsvCount`), `pushThreadArchiveCsvToMesh`, `pushForumTagExportToMesh`, deep link `openThreadCsv`. Bundle: `npm run test:ci-phase704`.
**Phase 704 (v0.8.679):** Thread archive JSON & forum tag export — `thread-json-mixin.js`, `thread.json` spans (`guildThreadJsonCount`), `pushThreadArchiveJsonToMesh`, `pushForumTagExportToMesh`, deep link `openThreadJson`. Bundle: `npm run test:ci-phase704`.
**Phase 703 (v0.8.678):** Pin registry CSV & reaction summary export — `pin-csv-mixin.js`, `pin.csv` spans (`guildPinCsvCount`), `pushPinRegistryCsvToMesh`, `pushReactionSummaryExportToMesh`, deep link `openPinCsv`. Bundle: `npm run test:ci-phase703`.
**Phase 703 (v0.8.678):** Pin registry JSON & reaction summary export — `pin-json-mixin.js`, `pin.json` spans (`guildPinJsonCount`), `pushPinRegistryJsonToMesh`, `pushReactionSummaryExportToMesh`, deep link `openPinJson`. Bundle: `npm run test:ci-phase703`.
**Phase 702 (v0.8.677):** Poll registry CSV & scheduled message export — `poll-csv-mixin.js`, `poll.csv` spans (`guildPollCsvCount`), `pushPollRegistryCsvToMesh`, `pushScheduledMessageExportToMesh`, deep link `openPollCsv`. Bundle: `npm run test:ci-phase702`.
**Phase 702 (v0.8.677):** Poll registry JSON & scheduled message export — `poll-json-mixin.js`, `poll.json` spans (`guildPollJsonCount`), `pushPollRegistryJsonToMesh`, `pushScheduledMessageExportToMesh`, deep link `openPollJson`. Bundle: `npm run test:ci-phase702`.
**Phase 701 (v0.8.676):** Ban registry CSV & automod rule export — `ban-csv-mixin.js`, `ban.csv` spans (`guildBanCsvCount`), `pushBanRegistryCsvToMesh`, `pushAutomodRuleExportToMesh`, deep link `openBanCsv`. Bundle: `npm run test:ci-phase701`.
**Phase 701 (v0.8.676):** Ban registry JSON & automod rule export — `ban-json-mixin.js`, `ban.json` spans (`guildBanJsonCount`), `pushBanRegistryJsonToMesh`, `pushAutomodRuleExportToMesh`, deep link `openBanJson`. Bundle: `npm run test:ci-phase701`.
**Phase 700 (v0.8.675):** Member roster CSV & moderation timeout export — `member-csv-mixin.js`, `member.csv` spans (`guildMemberCsvCount`), `pushMemberRosterCsvToMesh`, `pushModerationTimeoutExportToMesh`, deep link `openMemberCsv`. Bundle: `npm run test:ci-phase700`.
**Phase 700 (v0.8.675):** Member roster JSON & moderation timeout export — `member-json-mixin.js`, `member.json` spans (`guildMemberJsonCount`), `pushMemberRosterJsonToMesh`, `pushModerationTimeoutExportToMesh`, deep link `openMemberJson`. Bundle: `npm run test:ci-phase700`.
**Phase 699 (v0.8.674):** Emoji registry CSV & sticker pack export — `emoji-csv-mixin.js`, `emoji.csv` spans (`guildEmojiCsvCount`), `pushEmojiRegistryCsvToMesh`, `pushStickerPackExportToMesh`, deep link `openEmojiCsv`. Bundle: `npm run test:ci-phase699`.
**Phase 699 (v0.8.674):** Emoji registry JSON & sticker pack export — `emoji-json-mixin.js`, `emoji.json` spans (`guildEmojiJsonCount`), `pushEmojiRegistryJsonToMesh`, `pushStickerPackExportToMesh`, deep link `openEmojiJson`. Bundle: `npm run test:ci-phase699`.
**Phase 698 (v0.8.673):** Role override CSV & effective permission export — `permission-csv-mixin.js`, `permission.csv` spans (`guildPermissionCsvCount`), `pushRoleOverrideCsvToMesh`, `pushEffectivePermissionExportToMesh`, deep link `openPermissionCsv`. Bundle: `npm run test:ci-phase698`.
**Phase 698 (v0.8.673):** Role override JSON & effective permission export — `permission-json-mixin.js`, `permission.json` spans (`guildPermissionJsonCount`), `pushRoleOverrideJsonToMesh`, `pushEffectivePermissionExportToMesh`, deep link `openPermissionJson`. Bundle: `npm run test:ci-phase698`.
**Phase 697 (v0.8.672):** Invite link CSV & vanity URL export — `invite-csv-mixin.js`, `invite.csv` spans (`guildInviteCsvCount`), `pushInviteLinkCsvToMesh`, `pushVanityUrlExportToMesh`, deep link `openInviteCsv`. Bundle: `npm run test:ci-phase697`.
**Phase 697 (v0.8.672):** Invite link JSON & vanity URL export — `invite-json-mixin.js`, `invite.json` spans (`guildInviteJsonCount`), `pushInviteLinkJsonToMesh`, `pushVanityUrlExportToMesh`, deep link `openInviteJson`. Bundle: `npm run test:ci-phase697`.
**Phase 696 (v0.8.671):** OAuth grant CSV & install token export — `oauth-csv-mixin.js`, `oauth.csv` spans (`guildOAuthGrantCount`), `pushOAuthGrantCsvToMesh`, `pushOAuthInstallTokenExportToMesh`, deep link `openOAuthCsv`. Bundle: `npm run test:ci-phase696`.
**Phase 696 (v0.8.671):** OAuth grant JSON & install token export — `oauth-json-mixin.js`, `oauth.json` spans (`guildOAuthGrantCount`), `pushOAuthGrantJsonToMesh`, `pushOAuthInstallTokenExportToMesh`, deep link `openOAuthJson`. Bundle: `npm run test:ci-phase696`.
**Phase 695 (v0.8.670):** Slash registry CSV & invoke audit — `slash-csv-mixin.js`, `slash.csv` spans (`guildSlashRegistryCount`), `pushSlashRegistryCsvToMesh`, `pushSlashInvokeAuditExportToMesh`, deep link `openSlashCsv`. Bundle: `npm run test:ci-phase695`.
**Phase 695 (v0.8.670):** Slash registry JSON & invoke audit — `slash-json-mixin.js`, `slash.json` spans (`guildSlashRegistryCount`), `pushSlashRegistryJsonToMesh`, `pushSlashInvokeAuditExportToMesh`, deep link `openSlashJson`. Bundle: `npm run test:ci-phase695`.
**Phase 692 (v0.8.667):** Digest relay handoff CSV & archive export — `relay-csv-mixin.js`, `relay.csv` spans, `pushDigestRelayHandoffCsvToMesh`, `pushArchivePeerExportToMesh`, deep link `openRelayCsv`. Bundle: `npm run test:ci-phase692`.
**Phase 692 (v0.8.667):** Digest relay handoff JSON & archive export — `relay-json-mixin.js`, `relay.json` spans, `pushDigestRelayHandoffJsonToMesh`, `pushArchivePeerExportToMesh`, deep link `openRelayJson`. Bundle: `npm run test:ci-phase692`.
**Phase 693 (v0.8.668):** Worker release CSV & integration manifest — `worker-csv-mixin.js`, `worker.csv` spans (`guildWorkerReleaseCount`), `pushWorkerReleaseCsvToMesh`, `pushIntegrationManifestExportToMesh`, deep link `openWorkerCsv`. Bundle: `npm run test:ci-phase693`.
**Phase 693 (v0.8.668):** Worker release JSON & integration manifest — `worker-json-mixin.js`, `worker.json` spans (`guildWorkerReleaseCount`), `pushWorkerReleaseJsonToMesh`, `pushIntegrationManifestExportToMesh`, deep link `openWorkerJson`. Bundle: `npm run test:ci-phase693`.
**Phase 694 (v0.8.669):** Bot registry CSV & webhook execute — `bot-csv-mixin.js`, `bot.csv` spans (`guildBotRegistryCount`), `pushBotRegistryCsvToMesh`, `pushWebhookExecuteExportToMesh`, deep link `openBotCsv`. Bundle: `npm run test:ci-phase694`.
**Phase 694 (v0.8.669):** Bot registry JSON & webhook execute — `bot-json-mixin.js`, `bot.json` spans (`guildBotRegistryCount`), `pushBotRegistryJsonToMesh`, `pushWebhookExecuteExportToMesh`, deep link `openBotJson`. Bundle: `npm run test:ci-phase694`.
**Phase 691 (v0.8.666):** Hook failure digest CSV & compliance snapshot — `digest-csv-mixin.js`, `digest.csv` spans (`guildDigestCsvCount`), CSV gossip dedupe, `_healHookFailureDigestCsvCursorOnPartition` + `_healComplianceSnapshotCursorOnPartition`, `clearHookFailureDigestCsvExports`, `getLastComplianceSnapshot`, deep link `openDigestCsv`. Bundle: `npm run test:ci-phase691`.
**Phase 691 (v0.8.666):** Hook failure digest JSON & compliance snapshot — `digest-json-mixin.js`, `digest.json` spans (`guildDigestJsonCount`), JSON gossip dedupe, `_healHookFailureDigestJsonCursorOnPartition` + `_healComplianceSnapshotCursorOnPartition`, `clearHookFailureDigestJsonExports`, `getLastComplianceSnapshot`, deep link `openDigestJson`. Bundle: `npm run test:ci-phase691`.
**Phase 690 (v0.8.665):** Audit CSV mesh push & mod digest notify — `audit-csv-mixin.js`, `audit.csv` spans (`guildCsvExportCount`), CSV gossip dedupe, `_healAuditCsvExportCursorOnPartition` + `_healModDigestNotifyCursorOnPartition`, `clearModDigestNotifyPrefs`, deep link `openAuditCsv`. Bundle: `npm run test:ci-phase690`.
**Phase 690 (v0.8.665):** Audit JSON mesh push & mod digest notify — `audit-json-mixin.js`, `audit.json` spans (`guildJsonExportCount`), JSON gossip dedupe, `_healAuditJsonExportCursorOnPartition` + `_healModDigestNotifyCursorOnPartition`, `clearModDigestNotifyPrefs`, deep link `openAuditJson`. Bundle: `npm run test:ci-phase690`.
**Phase 689 (v0.8.664):** Integration health dashboard — `health-mixin.js`, `automation.health` spans (`guildHealthRowCount`), digest relay handoff gossip dedupe, `_healScheduleDashboardOnPartition` + `_healArchivePeerCursorOnPartition`, `clearDigestRelayHandoffs`, deep link `openHealth`. Bundle: `npm run test:ci-phase689`.
@@ -68,7 +68,7 @@ Application facade: one `PearcordPlatform` class that wires identity, database,
**Phase 679 (v0.8.654):** Thread panel & forum parity — `threads-forum.js` mixin, `createThread` auto-archive, `_healThreadMetadataOnPartition` watermark + auto-archive heal, guild-scoped `buildThreadsPanel`, deep link `create-thread` query. Bundle: `npm run test:ci-phase679`.
**Phase 697 (v0.8.672):** Invite link CSV uses `invites-discovery.js` + `listGuildInvites` for signed invite rows; vanity export from `vanityInviteCode` prefs. See [INVITE_LINK_CSV.md](../../docs/INVITE_LINK_CSV.md).
**Phase 697 (v0.8.672):** Invite link JSON uses `invites-discovery.js` + `listGuildInvites` for signed invite rows; vanity export from `vanityInviteCode` prefs. See [INVITE_LINK_JSON.md](../../docs/INVITE_LINK_JSON.md).
**Phase 678 (v0.8.653):** Invites & discovery join — `invites-discovery.js` mixin (`listGuildInvites`, `_healInvitesOnPartition`, `_healDiscoveryListingsOnPartition`, `_shouldGossipInvite`); view `guildInvites`, `inviteCount`, `discoveryListingVersion`; `createInvite` ttl/maxUses validation. Bundle: `npm run test:ci-phase678`.
@@ -1,67 +1,67 @@
'use strict'
const activityCsvMixin = {
_activityRegistryCsvGossipKeys: null,
_activityCsvHealWatermark: null,
_profileBannerExportCsvHealWatermark: null,
const activityJsonMixin = {
_activityRegistryJsonGossipKeys: null,
_activityJsonHealWatermark: null,
_profileBannerExportJsonHealWatermark: null,
_initActivityCsvMixinState () {
if (!this._activityRegistryCsvGossipKeys) {
this._activityRegistryCsvGossipKeys = new Set()
_initActivityJsonMixinState () {
if (!this._activityRegistryJsonGossipKeys) {
this._activityRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipActivityInviteRegistryCsv (slice) {
this._initActivityCsvMixinState()
_shouldGossipActivityInviteRegistryJson (slice) {
this._initActivityJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._activityRegistryCsvGossipKeys.has(hash)) return false
this._activityRegistryCsvGossipKeys.add(hash)
if (this._activityRegistryCsvGossipKeys.size > 8192) {
const first = this._activityRegistryCsvGossipKeys.values().next().value
if (first) this._activityRegistryCsvGossipKeys.delete(first)
if (this._activityRegistryJsonGossipKeys.has(hash)) return false
this._activityRegistryJsonGossipKeys.add(hash)
if (this._activityRegistryJsonGossipKeys.size > 8192) {
const first = this._activityRegistryJsonGossipKeys.values().next().value
if (first) this._activityRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipProfileBannerExportCsv (slice) {
this._initActivityCsvMixinState()
_shouldGossipProfileBannerExportJson (slice) {
this._initActivityJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._activityRegistryCsvGossipKeys.has(hash)) return false
this._activityRegistryCsvGossipKeys.add(hash)
if (this._activityRegistryJsonGossipKeys.has(hash)) return false
this._activityRegistryJsonGossipKeys.add(hash)
return true
},
async _healActivityInviteExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('activity.csv', {
spanKind: 'activity.csv',
const span = this.log.time('activity.json', {
spanKind: 'activity.json',
guildId: gid,
context: 'heal.activity'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildActivityCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildActivityJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listActivityInviteCsvExports(64)
const rows = await this.deliveryReceipts.listActivityInviteJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipActivityInviteRegistryCsv(row)) relisted++
if (this._shouldGossipActivityInviteRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._activityCsvHealWatermark = watermark
this._activityJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildActivityCsvCount: rows.length,
bridgeKind: 'activity.csv'
guildActivityJsonCount: rows.length,
bridgeKind: 'activity.json'
})
return { relisted, watermark, guildActivityCsvCount: rows.length }
return { relisted, watermark, guildActivityJsonCount: rows.length }
} catch (err) {
this.log.error('activity.csv error', {
this.log.error('activity.json error', {
guildId: gid,
context: 'heal.activity',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const activityCsvMixin = {
async _healProfileBannerExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('activity.csv', {
spanKind: 'activity.csv',
const span = this.log.time('activity.json', {
spanKind: 'activity.json',
guildId: gid,
context: 'heal.profile-banner'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildActivityCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildActivityJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listProfileBannerExportCsvExports(64)
const rows = await this.deliveryReceipts.listProfileBannerExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipProfileBannerExportCsv(row)) relisted++
if (this._shouldGossipProfileBannerExportJson(row)) relisted++
}
const watermark = Date.now()
this._profileBannerExportCsvHealWatermark = watermark
this._profileBannerExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildActivityCsvCount: rows.length,
guildActivityJsonCount: rows.length,
inviteCount: rows[0]?.inviteCount || 0,
bridgeKind: 'activity.csv'
bridgeKind: 'activity.json'
})
return { relisted, watermark, inviteCount: rows[0]?.inviteCount || 0 }
} catch (err) {
this.log.error('activity.csv error', {
this.log.error('activity.json error', {
guildId: gid,
context: 'heal.profile-banner',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const activityCsvMixin = {
}
}
module.exports = { activityCsvMixin }
module.exports = { activityJsonMixin }
+31 -31
View File
@@ -1,58 +1,58 @@
'use strict'
const auditCsvMixin = {
_auditExportCsvGossipKeys: null,
_auditCsvHealWatermark: null,
const auditJsonMixin = {
_auditExportJsonGossipKeys: null,
_auditJsonHealWatermark: null,
_modDigestNotifyHealWatermark: null,
_initAuditCsvMixinState () {
if (!this._auditExportCsvGossipKeys) {
this._auditExportCsvGossipKeys = new Set()
_initAuditJsonMixinState () {
if (!this._auditExportJsonGossipKeys) {
this._auditExportJsonGossipKeys = new Set()
}
},
_shouldGossipAuditExportCsv (slice) {
this._initAuditCsvMixinState()
_shouldGossipAuditExportJson (slice) {
this._initAuditJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}:${slice.filter || ''}`
if (this._auditExportCsvGossipKeys.has(hash)) return false
this._auditExportCsvGossipKeys.add(hash)
if (this._auditExportCsvGossipKeys.size > 8192) {
const first = this._auditExportCsvGossipKeys.values().next().value
if (first) this._auditExportCsvGossipKeys.delete(first)
if (this._auditExportJsonGossipKeys.has(hash)) return false
this._auditExportJsonGossipKeys.add(hash)
if (this._auditExportJsonGossipKeys.size > 8192) {
const first = this._auditExportJsonGossipKeys.values().next().value
if (first) this._auditExportJsonGossipKeys.delete(first)
}
return true
},
async _healAuditCsvExportCursorOnPartition (guildId) {
async _healAuditJsonExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('audit.csv', {
spanKind: 'audit.csv',
const span = this.log.time('audit.json', {
spanKind: 'audit.json',
guildId: gid,
context: 'heal.export'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildCsvExportCount: 0 })
span.end({ relisted: 0, skipped: true, guildJsonExportCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listAuditExportCsvExports(64)
const rows = await this.deliveryReceipts.listAuditExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipAuditExportCsv(row)) relisted++
if (this._shouldGossipAuditExportJson(row)) relisted++
}
const watermark = Date.now()
this._auditCsvHealWatermark = watermark
this._auditJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildCsvExportCount: rows.length,
bridgeKind: 'audit.csv'
guildJsonExportCount: rows.length,
bridgeKind: 'audit.json'
})
return { relisted, watermark, guildCsvExportCount: rows.length }
return { relisted, watermark, guildJsonExportCount: rows.length }
} catch (err) {
this.log.error('audit.csv error', {
this.log.error('audit.json error', {
guildId: gid,
context: 'heal.export',
error: err?.message || String(err)
@@ -64,14 +64,14 @@ const auditCsvMixin = {
async _healModDigestNotifyCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('audit.csv', {
spanKind: 'audit.csv',
const span = this.log.time('audit.json', {
spanKind: 'audit.json',
guildId: gid,
context: 'heal.modDigest'
})
try {
if (!gid) {
span.end({ relisted: 0, skipped: true, guildCsvExportCount: 0 })
span.end({ relisted: 0, skipped: true, guildJsonExportCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
@@ -81,9 +81,9 @@ const auditCsvMixin = {
span.end({
relisted: prefs.modDigestGroupDmEnabled ? 1 : 0,
watermark,
guildCsvExportCount: 0,
guildJsonExportCount: 0,
modDigestEnabled: !!prefs.modDigestGroupDmEnabled,
bridgeKind: 'audit.csv'
bridgeKind: 'audit.json'
})
return {
relisted: prefs.modDigestGroupDmEnabled ? 1 : 0,
@@ -91,7 +91,7 @@ const auditCsvMixin = {
modDigestEnabled: !!prefs.modDigestGroupDmEnabled
}
} catch (err) {
this.log.error('audit.csv error', {
this.log.error('audit.json error', {
guildId: gid,
context: 'heal.modDigest',
error: err?.message || String(err)
@@ -102,4 +102,4 @@ const auditCsvMixin = {
}
}
module.exports = { auditCsvMixin }
module.exports = { auditJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const banCsvMixin = {
_banRegistryCsvGossipKeys: null,
_banCsvHealWatermark: null,
_automodRuleCsvHealWatermark: null,
const banJsonMixin = {
_banRegistryJsonGossipKeys: null,
_banJsonHealWatermark: null,
_automodRuleJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._banRegistryCsvGossipKeys) {
this._banRegistryCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._banRegistryJsonGossipKeys) {
this._banRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipBanRegistryCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipBanRegistryJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._banRegistryCsvGossipKeys.has(hash)) return false
this._banRegistryCsvGossipKeys.add(hash)
if (this._banRegistryCsvGossipKeys.size > 8192) {
const first = this._banRegistryCsvGossipKeys.values().next().value
if (first) this._banRegistryCsvGossipKeys.delete(first)
if (this._banRegistryJsonGossipKeys.has(hash)) return false
this._banRegistryJsonGossipKeys.add(hash)
if (this._banRegistryJsonGossipKeys.size > 8192) {
const first = this._banRegistryJsonGossipKeys.values().next().value
if (first) this._banRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipAutomodRuleExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipAutomodRuleExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._banRegistryCsvGossipKeys.has(hash)) return false
this._banRegistryCsvGossipKeys.add(hash)
if (this._banRegistryJsonGossipKeys.has(hash)) return false
this._banRegistryJsonGossipKeys.add(hash)
return true
},
async _healBanRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('ban.csv', {
spanKind: 'ban.csv',
const span = this.log.time('ban.json', {
spanKind: 'ban.json',
guildId: gid,
context: 'heal.ban'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildBanCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildBanJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listBanRegistryCsvExports(64)
const rows = await this.deliveryReceipts.listBanRegistryJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipBanRegistryCsv(row)) relisted++
if (this._shouldGossipBanRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._banCsvHealWatermark = watermark
this._banJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildBanCsvCount: rows.length,
bridgeKind: 'ban.csv'
guildBanJsonCount: rows.length,
bridgeKind: 'ban.json'
})
return { relisted, watermark, guildBanCsvCount: rows.length }
return { relisted, watermark, guildBanJsonCount: rows.length }
} catch (err) {
this.log.error('ban.csv error', {
this.log.error('ban.json error', {
guildId: gid,
context: 'heal.ban',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const banCsvMixin = {
async _healAutomodRuleExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('ban.csv', {
spanKind: 'ban.csv',
const span = this.log.time('ban.json', {
spanKind: 'ban.json',
guildId: gid,
context: 'heal.automod'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildBanCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildBanJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listAutomodRuleExportCsvExports(64)
const rows = await this.deliveryReceipts.listAutomodRuleExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipAutomodRuleExportCsv(row)) relisted++
if (this._shouldGossipAutomodRuleExportJson(row)) relisted++
}
const watermark = Date.now()
this._automodRuleCsvHealWatermark = watermark
this._automodRuleJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildBanCsvCount: rows.length,
guildBanJsonCount: rows.length,
banCount: rows[0]?.banCount || 0,
bridgeKind: 'ban.csv'
bridgeKind: 'ban.json'
})
return { relisted, watermark, banCount: rows[0]?.banCount || 0 }
} catch (err) {
this.log.error('ban.csv error', {
this.log.error('ban.json error', {
guildId: gid,
context: 'heal.automod',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const banCsvMixin = {
}
}
module.exports = { banCsvMixin }
module.exports = { banJsonMixin }
+33 -33
View File
@@ -1,42 +1,42 @@
'use strict'
const botCsvMixin = {
_botRegistryCsvGossipKeys: null,
_botCsvHealWatermark: null,
_webhookExecuteCsvHealWatermark: null,
const botJsonMixin = {
_botRegistryJsonGossipKeys: null,
_botJsonHealWatermark: null,
_webhookExecuteJsonHealWatermark: null,
_initBotCsvMixinState () {
if (!this._botRegistryCsvGossipKeys) {
this._botRegistryCsvGossipKeys = new Set()
_initBotJsonMixinState () {
if (!this._botRegistryJsonGossipKeys) {
this._botRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipBotRegistryCsv (slice) {
this._initBotCsvMixinState()
_shouldGossipBotRegistryJson (slice) {
this._initBotJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._botRegistryCsvGossipKeys.has(hash)) return false
this._botRegistryCsvGossipKeys.add(hash)
if (this._botRegistryCsvGossipKeys.size > 8192) {
const first = this._botRegistryCsvGossipKeys.values().next().value
if (first) this._botRegistryCsvGossipKeys.delete(first)
if (this._botRegistryJsonGossipKeys.has(hash)) return false
this._botRegistryJsonGossipKeys.add(hash)
if (this._botRegistryJsonGossipKeys.size > 8192) {
const first = this._botRegistryJsonGossipKeys.values().next().value
if (first) this._botRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipWebhookExecuteExportCsv (slice) {
this._initBotCsvMixinState()
_shouldGossipWebhookExecuteExportJson (slice) {
this._initBotJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `webhook:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._botRegistryCsvGossipKeys.has(hash)) return false
this._botRegistryCsvGossipKeys.add(hash)
if (this._botRegistryJsonGossipKeys.has(hash)) return false
this._botRegistryJsonGossipKeys.add(hash)
return true
},
async _healBotRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('bot.csv', {
spanKind: 'bot.csv',
const span = this.log.time('bot.json', {
spanKind: 'bot.json',
guildId: gid,
context: 'heal.registry'
})
@@ -46,22 +46,22 @@ const botCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listBotRegistryCsvExports(64)
const rows = await this.deliveryReceipts.listBotRegistryJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipBotRegistryCsv(row)) relisted++
if (this._shouldGossipBotRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._botCsvHealWatermark = watermark
this._botJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildBotRegistryCount: rows.length,
bridgeKind: 'bot.csv'
bridgeKind: 'bot.json'
})
return { relisted, watermark, guildBotRegistryCount: rows.length }
} catch (err) {
this.log.error('bot.csv error', {
this.log.error('bot.json error', {
guildId: gid,
context: 'heal.registry',
error: err?.message || String(err)
@@ -73,8 +73,8 @@ const botCsvMixin = {
async _healWebhookExecuteExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('bot.csv', {
spanKind: 'bot.csv',
const span = this.log.time('bot.json', {
spanKind: 'bot.json',
guildId: gid,
context: 'heal.execute'
})
@@ -84,23 +84,23 @@ const botCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listWebhookExecuteExportCsvExports(64)
const rows = await this.deliveryReceipts.listWebhookExecuteExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipWebhookExecuteExportCsv(row)) relisted++
if (this._shouldGossipWebhookExecuteExportJson(row)) relisted++
}
const watermark = Date.now()
this._webhookExecuteCsvHealWatermark = watermark
this._webhookExecuteJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildBotRegistryCount: rows.length,
webhookCount: rows[0]?.webhookCount || 0,
bridgeKind: 'bot.csv'
bridgeKind: 'bot.json'
})
return { relisted, watermark, webhookCount: rows[0]?.webhookCount || 0 }
} catch (err) {
this.log.error('bot.csv error', {
this.log.error('bot.json error', {
guildId: gid,
context: 'heal.execute',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const botCsvMixin = {
}
}
module.exports = { botCsvMixin }
module.exports = { botJsonMixin }
+31 -31
View File
@@ -1,58 +1,58 @@
'use strict'
const digestCsvMixin = {
_hookFailureDigestCsvGossipKeys: null,
_digestCsvHealWatermark: null,
const digestJsonMixin = {
_hookFailureDigestJsonGossipKeys: null,
_digestJsonHealWatermark: null,
_complianceSnapshotHealWatermark: null,
_initDigestCsvMixinState () {
if (!this._hookFailureDigestCsvGossipKeys) {
this._hookFailureDigestCsvGossipKeys = new Set()
_initDigestJsonMixinState () {
if (!this._hookFailureDigestJsonGossipKeys) {
this._hookFailureDigestJsonGossipKeys = new Set()
}
},
_shouldGossipHookFailureDigestCsv (slice) {
this._initDigestCsvMixinState()
_shouldGossipHookFailureDigestJson (slice) {
this._initDigestJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._hookFailureDigestCsvGossipKeys.has(hash)) return false
this._hookFailureDigestCsvGossipKeys.add(hash)
if (this._hookFailureDigestCsvGossipKeys.size > 8192) {
const first = this._hookFailureDigestCsvGossipKeys.values().next().value
if (first) this._hookFailureDigestCsvGossipKeys.delete(first)
if (this._hookFailureDigestJsonGossipKeys.has(hash)) return false
this._hookFailureDigestJsonGossipKeys.add(hash)
if (this._hookFailureDigestJsonGossipKeys.size > 8192) {
const first = this._hookFailureDigestJsonGossipKeys.values().next().value
if (first) this._hookFailureDigestJsonGossipKeys.delete(first)
}
return true
},
async _healHookFailureDigestCsvCursorOnPartition (guildId) {
async _healHookFailureDigestJsonCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('digest.csv', {
spanKind: 'digest.csv',
const span = this.log.time('digest.json', {
spanKind: 'digest.json',
guildId: gid,
context: 'heal.export'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildDigestCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildDigestJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listHookFailureDigestCsvExports(64)
const rows = await this.deliveryReceipts.listHookFailureDigestJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipHookFailureDigestCsv(row)) relisted++
if (this._shouldGossipHookFailureDigestJson(row)) relisted++
}
const watermark = Date.now()
this._digestCsvHealWatermark = watermark
this._digestJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildDigestCsvCount: rows.length,
bridgeKind: 'digest.csv'
guildDigestJsonCount: rows.length,
bridgeKind: 'digest.json'
})
return { relisted, watermark, guildDigestCsvCount: rows.length }
return { relisted, watermark, guildDigestJsonCount: rows.length }
} catch (err) {
this.log.error('digest.csv error', {
this.log.error('digest.json error', {
guildId: gid,
context: 'heal.export',
error: err?.message || String(err)
@@ -64,14 +64,14 @@ const digestCsvMixin = {
async _healComplianceSnapshotCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('digest.csv', {
spanKind: 'digest.csv',
const span = this.log.time('digest.json', {
spanKind: 'digest.json',
guildId: gid,
context: 'heal.compliance'
})
try {
if (!gid) {
span.end({ relisted: 0, skipped: true, guildDigestCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildDigestJsonCount: 0 })
return { relisted: 0, skipped: true }
}
const watermark = Date.now()
@@ -80,13 +80,13 @@ const digestCsvMixin = {
span.end({
relisted: snap ? 1 : 0,
watermark,
guildDigestCsvCount: 0,
guildDigestJsonCount: 0,
entryCount: snap?.count || 0,
bridgeKind: 'digest.csv'
bridgeKind: 'digest.json'
})
return { relisted: snap ? 1 : 0, watermark, entryCount: snap?.count || 0 }
} catch (err) {
this.log.error('digest.csv error', {
this.log.error('digest.json error', {
guildId: gid,
context: 'heal.compliance',
error: err?.message || String(err)
@@ -97,4 +97,4 @@ const digestCsvMixin = {
}
}
module.exports = { digestCsvMixin }
module.exports = { digestJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const emojiCsvMixin = {
_emojiRegistryCsvGossipKeys: null,
_emojiCsvHealWatermark: null,
_stickerPackCsvHealWatermark: null,
const emojiJsonMixin = {
_emojiRegistryJsonGossipKeys: null,
_emojiJsonHealWatermark: null,
_stickerPackJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._emojiRegistryCsvGossipKeys) {
this._emojiRegistryCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._emojiRegistryJsonGossipKeys) {
this._emojiRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipEmojiRegistryCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipEmojiRegistryJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._emojiRegistryCsvGossipKeys.has(hash)) return false
this._emojiRegistryCsvGossipKeys.add(hash)
if (this._emojiRegistryCsvGossipKeys.size > 8192) {
const first = this._emojiRegistryCsvGossipKeys.values().next().value
if (first) this._emojiRegistryCsvGossipKeys.delete(first)
if (this._emojiRegistryJsonGossipKeys.has(hash)) return false
this._emojiRegistryJsonGossipKeys.add(hash)
if (this._emojiRegistryJsonGossipKeys.size > 8192) {
const first = this._emojiRegistryJsonGossipKeys.values().next().value
if (first) this._emojiRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipStickerPackExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipStickerPackExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._emojiRegistryCsvGossipKeys.has(hash)) return false
this._emojiRegistryCsvGossipKeys.add(hash)
if (this._emojiRegistryJsonGossipKeys.has(hash)) return false
this._emojiRegistryJsonGossipKeys.add(hash)
return true
},
async _healEmojiRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('emoji.csv', {
spanKind: 'emoji.csv',
const span = this.log.time('emoji.json', {
spanKind: 'emoji.json',
guildId: gid,
context: 'heal.emoji'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildEmojiCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildEmojiJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listEmojiRegistryCsvExports(64)
const rows = await this.deliveryReceipts.listEmojiRegistryJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipEmojiRegistryCsv(row)) relisted++
if (this._shouldGossipEmojiRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._emojiCsvHealWatermark = watermark
this._emojiJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildEmojiCsvCount: rows.length,
bridgeKind: 'emoji.csv'
guildEmojiJsonCount: rows.length,
bridgeKind: 'emoji.json'
})
return { relisted, watermark, guildEmojiCsvCount: rows.length }
return { relisted, watermark, guildEmojiJsonCount: rows.length }
} catch (err) {
this.log.error('emoji.csv error', {
this.log.error('emoji.json error', {
guildId: gid,
context: 'heal.emoji',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const emojiCsvMixin = {
async _healStickerPackExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('emoji.csv', {
spanKind: 'emoji.csv',
const span = this.log.time('emoji.json', {
spanKind: 'emoji.json',
guildId: gid,
context: 'heal.sticker'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildEmojiCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildEmojiJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listStickerPackExportCsvExports(64)
const rows = await this.deliveryReceipts.listStickerPackExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipStickerPackExportCsv(row)) relisted++
if (this._shouldGossipStickerPackExportJson(row)) relisted++
}
const watermark = Date.now()
this._stickerPackCsvHealWatermark = watermark
this._stickerPackJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildEmojiCsvCount: rows.length,
guildEmojiJsonCount: rows.length,
emojiCount: rows[0]?.emojiCount || 0,
bridgeKind: 'emoji.csv'
bridgeKind: 'emoji.json'
})
return { relisted, watermark, emojiCount: rows[0]?.emojiCount || 0 }
} catch (err) {
this.log.error('emoji.csv error', {
this.log.error('emoji.json error', {
guildId: gid,
context: 'heal.sticker',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const emojiCsvMixin = {
}
}
module.exports = { emojiCsvMixin }
module.exports = { emojiJsonMixin }
+2126 -2123
View File
File diff suppressed because it is too large Load Diff
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const inviteCsvMixin = {
_inviteLinkCsvGossipKeys: null,
_inviteCsvHealWatermark: null,
_vanityUrlCsvHealWatermark: null,
const inviteJsonMixin = {
_inviteLinkJsonGossipKeys: null,
_inviteJsonHealWatermark: null,
_vanityUrlJsonHealWatermark: null,
_initInviteCsvMixinState () {
if (!this._inviteLinkCsvGossipKeys) {
this._inviteLinkCsvGossipKeys = new Set()
_initInviteJsonMixinState () {
if (!this._inviteLinkJsonGossipKeys) {
this._inviteLinkJsonGossipKeys = new Set()
}
},
_shouldGossipInviteLinkCsv (slice) {
this._initInviteCsvMixinState()
_shouldGossipInviteLinkJson (slice) {
this._initInviteJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._inviteLinkCsvGossipKeys.has(hash)) return false
this._inviteLinkCsvGossipKeys.add(hash)
if (this._inviteLinkCsvGossipKeys.size > 8192) {
const first = this._inviteLinkCsvGossipKeys.values().next().value
if (first) this._inviteLinkCsvGossipKeys.delete(first)
if (this._inviteLinkJsonGossipKeys.has(hash)) return false
this._inviteLinkJsonGossipKeys.add(hash)
if (this._inviteLinkJsonGossipKeys.size > 8192) {
const first = this._inviteLinkJsonGossipKeys.values().next().value
if (first) this._inviteLinkJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipVanityUrlExportCsv (slice) {
this._initInviteCsvMixinState()
_shouldGossipVanityUrlExportJson (slice) {
this._initInviteJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `vanity:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._inviteLinkCsvGossipKeys.has(hash)) return false
this._inviteLinkCsvGossipKeys.add(hash)
if (this._inviteLinkJsonGossipKeys.has(hash)) return false
this._inviteLinkJsonGossipKeys.add(hash)
return true
},
async _healInviteLinkExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('invite.csv', {
spanKind: 'invite.csv',
const span = this.log.time('invite.json', {
spanKind: 'invite.json',
guildId: gid,
context: 'heal.link'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildInviteCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildInviteJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listInviteLinkCsvExports(64)
const rows = await this.deliveryReceipts.listInviteLinkJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipInviteLinkCsv(row)) relisted++
if (this._shouldGossipInviteLinkJson(row)) relisted++
}
const watermark = Date.now()
this._inviteCsvHealWatermark = watermark
this._inviteJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildInviteCsvCount: rows.length,
bridgeKind: 'invite.csv'
guildInviteJsonCount: rows.length,
bridgeKind: 'invite.json'
})
return { relisted, watermark, guildInviteCsvCount: rows.length }
return { relisted, watermark, guildInviteJsonCount: rows.length }
} catch (err) {
this.log.error('invite.csv error', {
this.log.error('invite.json error', {
guildId: gid,
context: 'heal.link',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const inviteCsvMixin = {
async _healVanityUrlExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('invite.csv', {
spanKind: 'invite.csv',
const span = this.log.time('invite.json', {
spanKind: 'invite.json',
guildId: gid,
context: 'heal.vanity'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildInviteCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildInviteJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listVanityUrlExportCsvExports(64)
const rows = await this.deliveryReceipts.listVanityUrlExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipVanityUrlExportCsv(row)) relisted++
if (this._shouldGossipVanityUrlExportJson(row)) relisted++
}
const watermark = Date.now()
this._vanityUrlCsvHealWatermark = watermark
this._vanityUrlJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildInviteCsvCount: rows.length,
guildInviteJsonCount: rows.length,
inviteCount: rows[0]?.inviteCount || 0,
bridgeKind: 'invite.csv'
bridgeKind: 'invite.json'
})
return { relisted, watermark, inviteCount: rows[0]?.inviteCount || 0 }
} catch (err) {
this.log.error('invite.csv error', {
this.log.error('invite.json error', {
guildId: gid,
context: 'heal.vanity',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const inviteCsvMixin = {
}
}
module.exports = { inviteCsvMixin }
module.exports = { inviteJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const memberCsvMixin = {
_memberRosterCsvGossipKeys: null,
_memberCsvHealWatermark: null,
_moderationTimeoutCsvHealWatermark: null,
const memberJsonMixin = {
_memberRosterJsonGossipKeys: null,
_memberJsonHealWatermark: null,
_moderationTimeoutJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._memberRosterCsvGossipKeys) {
this._memberRosterCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._memberRosterJsonGossipKeys) {
this._memberRosterJsonGossipKeys = new Set()
}
},
_shouldGossipMemberRosterCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipMemberRosterJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._memberRosterCsvGossipKeys.has(hash)) return false
this._memberRosterCsvGossipKeys.add(hash)
if (this._memberRosterCsvGossipKeys.size > 8192) {
const first = this._memberRosterCsvGossipKeys.values().next().value
if (first) this._memberRosterCsvGossipKeys.delete(first)
if (this._memberRosterJsonGossipKeys.has(hash)) return false
this._memberRosterJsonGossipKeys.add(hash)
if (this._memberRosterJsonGossipKeys.size > 8192) {
const first = this._memberRosterJsonGossipKeys.values().next().value
if (first) this._memberRosterJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipModerationTimeoutExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipModerationTimeoutExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._memberRosterCsvGossipKeys.has(hash)) return false
this._memberRosterCsvGossipKeys.add(hash)
if (this._memberRosterJsonGossipKeys.has(hash)) return false
this._memberRosterJsonGossipKeys.add(hash)
return true
},
async _healMemberRosterExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('member.csv', {
spanKind: 'member.csv',
const span = this.log.time('member.json', {
spanKind: 'member.json',
guildId: gid,
context: 'heal.roster'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildMemberCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildMemberJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listMemberRosterCsvExports(64)
const rows = await this.deliveryReceipts.listMemberRosterJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipMemberRosterCsv(row)) relisted++
if (this._shouldGossipMemberRosterJson(row)) relisted++
}
const watermark = Date.now()
this._memberCsvHealWatermark = watermark
this._memberJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildMemberCsvCount: rows.length,
bridgeKind: 'member.csv'
guildMemberJsonCount: rows.length,
bridgeKind: 'member.json'
})
return { relisted, watermark, guildMemberCsvCount: rows.length }
return { relisted, watermark, guildMemberJsonCount: rows.length }
} catch (err) {
this.log.error('member.csv error', {
this.log.error('member.json error', {
guildId: gid,
context: 'heal.roster',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const memberCsvMixin = {
async _healModerationTimeoutExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('member.csv', {
spanKind: 'member.csv',
const span = this.log.time('member.json', {
spanKind: 'member.json',
guildId: gid,
context: 'heal.timeout'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildMemberCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildMemberJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listModerationTimeoutExportCsvExports(64)
const rows = await this.deliveryReceipts.listModerationTimeoutExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipModerationTimeoutExportCsv(row)) relisted++
if (this._shouldGossipModerationTimeoutExportJson(row)) relisted++
}
const watermark = Date.now()
this._moderationTimeoutCsvHealWatermark = watermark
this._moderationTimeoutJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildMemberCsvCount: rows.length,
guildMemberJsonCount: rows.length,
memberCount: rows[0]?.memberCount || 0,
bridgeKind: 'member.csv'
bridgeKind: 'member.json'
})
return { relisted, watermark, memberCount: rows[0]?.memberCount || 0 }
} catch (err) {
this.log.error('member.csv error', {
this.log.error('member.json error', {
guildId: gid,
context: 'heal.timeout',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const memberCsvMixin = {
}
}
module.exports = { memberCsvMixin }
module.exports = { memberJsonMixin }
@@ -1,67 +1,67 @@
'use strict'
const notificationCsvMixin = {
_notificationRegistryCsvGossipKeys: null,
_notificationCsvHealWatermark: null,
_channelFollowExportCsvHealWatermark: null,
const notificationJsonMixin = {
_notificationRegistryJsonGossipKeys: null,
_notificationJsonHealWatermark: null,
_channelFollowExportJsonHealWatermark: null,
_initNotificationCsvMixinState () {
if (!this._notificationRegistryCsvGossipKeys) {
this._notificationRegistryCsvGossipKeys = new Set()
_initNotificationJsonMixinState () {
if (!this._notificationRegistryJsonGossipKeys) {
this._notificationRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipNotificationRegistryCsv (slice) {
this._initNotificationCsvMixinState()
_shouldGossipNotificationRegistryJson (slice) {
this._initNotificationJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._notificationRegistryCsvGossipKeys.has(hash)) return false
this._notificationRegistryCsvGossipKeys.add(hash)
if (this._notificationRegistryCsvGossipKeys.size > 8192) {
const first = this._notificationRegistryCsvGossipKeys.values().next().value
if (first) this._notificationRegistryCsvGossipKeys.delete(first)
if (this._notificationRegistryJsonGossipKeys.has(hash)) return false
this._notificationRegistryJsonGossipKeys.add(hash)
if (this._notificationRegistryJsonGossipKeys.size > 8192) {
const first = this._notificationRegistryJsonGossipKeys.values().next().value
if (first) this._notificationRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipChannelFollowExportCsv (slice) {
this._initNotificationCsvMixinState()
_shouldGossipChannelFollowExportJson (slice) {
this._initNotificationJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._notificationRegistryCsvGossipKeys.has(hash)) return false
this._notificationRegistryCsvGossipKeys.add(hash)
if (this._notificationRegistryJsonGossipKeys.has(hash)) return false
this._notificationRegistryJsonGossipKeys.add(hash)
return true
},
async _healNotificationOverrideExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('notification.csv', {
spanKind: 'notification.csv',
const span = this.log.time('notification.json', {
spanKind: 'notification.json',
guildId: gid,
context: 'heal.notification'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildNotificationCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildNotificationJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listNotificationOverrideCsvExports(64)
const rows = await this.deliveryReceipts.listNotificationOverrideJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipNotificationRegistryCsv(row)) relisted++
if (this._shouldGossipNotificationRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._notificationCsvHealWatermark = watermark
this._notificationJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildNotificationCsvCount: rows.length,
bridgeKind: 'notification.csv'
guildNotificationJsonCount: rows.length,
bridgeKind: 'notification.json'
})
return { relisted, watermark, guildNotificationCsvCount: rows.length }
return { relisted, watermark, guildNotificationJsonCount: rows.length }
} catch (err) {
this.log.error('notification.csv error', {
this.log.error('notification.json error', {
guildId: gid,
context: 'heal.notification',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const notificationCsvMixin = {
async _healChannelFollowExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('notification.csv', {
spanKind: 'notification.csv',
const span = this.log.time('notification.json', {
spanKind: 'notification.json',
guildId: gid,
context: 'heal.channel-follow'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildNotificationCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildNotificationJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listChannelFollowExportCsvExports(64)
const rows = await this.deliveryReceipts.listChannelFollowExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipChannelFollowExportCsv(row)) relisted++
if (this._shouldGossipChannelFollowExportJson(row)) relisted++
}
const watermark = Date.now()
this._channelFollowExportCsvHealWatermark = watermark
this._channelFollowExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildNotificationCsvCount: rows.length,
guildNotificationJsonCount: rows.length,
overrideCount: rows[0]?.overrideCount || 0,
bridgeKind: 'notification.csv'
bridgeKind: 'notification.json'
})
return { relisted, watermark, overrideCount: rows[0]?.overrideCount || 0 }
} catch (err) {
this.log.error('notification.csv error', {
this.log.error('notification.json error', {
guildId: gid,
context: 'heal.channel-follow',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const notificationCsvMixin = {
}
}
module.exports = { notificationCsvMixin }
module.exports = { notificationJsonMixin }
+33 -33
View File
@@ -1,42 +1,42 @@
'use strict'
const oauthCsvMixin = {
_oauthGrantCsvGossipKeys: null,
_oauthCsvHealWatermark: null,
_oauthInstallTokenCsvHealWatermark: null,
const oauthJsonMixin = {
_oauthGrantJsonGossipKeys: null,
_oauthJsonHealWatermark: null,
_oauthInstallTokenJsonHealWatermark: null,
_initOauthCsvMixinState () {
if (!this._oauthGrantCsvGossipKeys) {
this._oauthGrantCsvGossipKeys = new Set()
_initOauthJsonMixinState () {
if (!this._oauthGrantJsonGossipKeys) {
this._oauthGrantJsonGossipKeys = new Set()
}
},
_shouldGossipOAuthGrantCsv (slice) {
this._initOauthCsvMixinState()
_shouldGossipOAuthGrantJson (slice) {
this._initOauthJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._oauthGrantCsvGossipKeys.has(hash)) return false
this._oauthGrantCsvGossipKeys.add(hash)
if (this._oauthGrantCsvGossipKeys.size > 8192) {
const first = this._oauthGrantCsvGossipKeys.values().next().value
if (first) this._oauthGrantCsvGossipKeys.delete(first)
if (this._oauthGrantJsonGossipKeys.has(hash)) return false
this._oauthGrantJsonGossipKeys.add(hash)
if (this._oauthGrantJsonGossipKeys.size > 8192) {
const first = this._oauthGrantJsonGossipKeys.values().next().value
if (first) this._oauthGrantJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipOAuthInstallTokenExportCsv (slice) {
this._initOauthCsvMixinState()
_shouldGossipOAuthInstallTokenExportJson (slice) {
this._initOauthJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `install:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._oauthGrantCsvGossipKeys.has(hash)) return false
this._oauthGrantCsvGossipKeys.add(hash)
if (this._oauthGrantJsonGossipKeys.has(hash)) return false
this._oauthGrantJsonGossipKeys.add(hash)
return true
},
async _healOAuthGrantExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('oauth.csv', {
spanKind: 'oauth.csv',
const span = this.log.time('oauth.json', {
spanKind: 'oauth.json',
guildId: gid,
context: 'heal.grant'
})
@@ -46,22 +46,22 @@ const oauthCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listOAuthGrantCsvExports(64)
const rows = await this.deliveryReceipts.listOAuthGrantJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipOAuthGrantCsv(row)) relisted++
if (this._shouldGossipOAuthGrantJson(row)) relisted++
}
const watermark = Date.now()
this._oauthCsvHealWatermark = watermark
this._oauthJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildOAuthGrantCount: rows.length,
bridgeKind: 'oauth.csv'
bridgeKind: 'oauth.json'
})
return { relisted, watermark, guildOAuthGrantCount: rows.length }
} catch (err) {
this.log.error('oauth.csv error', {
this.log.error('oauth.json error', {
guildId: gid,
context: 'heal.grant',
error: err?.message || String(err)
@@ -73,8 +73,8 @@ const oauthCsvMixin = {
async _healOAuthInstallTokenExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('oauth.csv', {
spanKind: 'oauth.csv',
const span = this.log.time('oauth.json', {
spanKind: 'oauth.json',
guildId: gid,
context: 'heal.install'
})
@@ -84,23 +84,23 @@ const oauthCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listOAuthInstallTokenExportCsvExports(64)
const rows = await this.deliveryReceipts.listOAuthInstallTokenExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipOAuthInstallTokenExportCsv(row)) relisted++
if (this._shouldGossipOAuthInstallTokenExportJson(row)) relisted++
}
const watermark = Date.now()
this._oauthInstallTokenCsvHealWatermark = watermark
this._oauthInstallTokenJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildOAuthGrantCount: rows.length,
grantCount: rows[0]?.grantCount || 0,
bridgeKind: 'oauth.csv'
bridgeKind: 'oauth.json'
})
return { relisted, watermark, grantCount: rows[0]?.grantCount || 0 }
} catch (err) {
this.log.error('oauth.csv error', {
this.log.error('oauth.json error', {
guildId: gid,
context: 'heal.install',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const oauthCsvMixin = {
}
}
module.exports = { oauthCsvMixin }
module.exports = { oauthJsonMixin }
@@ -1,67 +1,67 @@
'use strict'
const permissionCsvMixin = {
_roleOverrideCsvGossipKeys: null,
_permissionCsvHealWatermark: null,
_effectivePermissionCsvHealWatermark: null,
const permissionJsonMixin = {
_roleOverrideJsonGossipKeys: null,
_permissionJsonHealWatermark: null,
_effectivePermissionJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._roleOverrideCsvGossipKeys) {
this._roleOverrideCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._roleOverrideJsonGossipKeys) {
this._roleOverrideJsonGossipKeys = new Set()
}
},
_shouldGossipRoleOverrideCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipRoleOverrideJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._roleOverrideCsvGossipKeys.has(hash)) return false
this._roleOverrideCsvGossipKeys.add(hash)
if (this._roleOverrideCsvGossipKeys.size > 8192) {
const first = this._roleOverrideCsvGossipKeys.values().next().value
if (first) this._roleOverrideCsvGossipKeys.delete(first)
if (this._roleOverrideJsonGossipKeys.has(hash)) return false
this._roleOverrideJsonGossipKeys.add(hash)
if (this._roleOverrideJsonGossipKeys.size > 8192) {
const first = this._roleOverrideJsonGossipKeys.values().next().value
if (first) this._roleOverrideJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipEffectivePermissionExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipEffectivePermissionExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._roleOverrideCsvGossipKeys.has(hash)) return false
this._roleOverrideCsvGossipKeys.add(hash)
if (this._roleOverrideJsonGossipKeys.has(hash)) return false
this._roleOverrideJsonGossipKeys.add(hash)
return true
},
async _healRoleOverrideExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('permission.csv', {
spanKind: 'permission.csv',
const span = this.log.time('permission.json', {
spanKind: 'permission.json',
guildId: gid,
context: 'heal.override'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPermissionCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPermissionJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listRoleOverrideCsvExports(64)
const rows = await this.deliveryReceipts.listRoleOverrideJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipRoleOverrideCsv(row)) relisted++
if (this._shouldGossipRoleOverrideJson(row)) relisted++
}
const watermark = Date.now()
this._permissionCsvHealWatermark = watermark
this._permissionJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPermissionCsvCount: rows.length,
bridgeKind: 'permission.csv'
guildPermissionJsonCount: rows.length,
bridgeKind: 'permission.json'
})
return { relisted, watermark, guildPermissionCsvCount: rows.length }
return { relisted, watermark, guildPermissionJsonCount: rows.length }
} catch (err) {
this.log.error('permission.csv error', {
this.log.error('permission.json error', {
guildId: gid,
context: 'heal.override',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const permissionCsvMixin = {
async _healEffectivePermissionExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('permission.csv', {
spanKind: 'permission.csv',
const span = this.log.time('permission.json', {
spanKind: 'permission.json',
guildId: gid,
context: 'heal.effective'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPermissionCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPermissionJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listEffectivePermissionExportCsvExports(64)
const rows = await this.deliveryReceipts.listEffectivePermissionExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipEffectivePermissionExportCsv(row)) relisted++
if (this._shouldGossipEffectivePermissionExportJson(row)) relisted++
}
const watermark = Date.now()
this._effectivePermissionCsvHealWatermark = watermark
this._effectivePermissionJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPermissionCsvCount: rows.length,
guildPermissionJsonCount: rows.length,
overwriteCount: rows[0]?.overwriteCount || 0,
bridgeKind: 'permission.csv'
bridgeKind: 'permission.json'
})
return { relisted, watermark, overwriteCount: rows[0]?.overwriteCount || 0 }
} catch (err) {
this.log.error('permission.csv error', {
this.log.error('permission.json error', {
guildId: gid,
context: 'heal.effective',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const permissionCsvMixin = {
}
}
module.exports = { permissionCsvMixin }
module.exports = { permissionJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const pinCsvMixin = {
_pinRegistryCsvGossipKeys: null,
_pinCsvHealWatermark: null,
_reactionSummaryCsvHealWatermark: null,
const pinJsonMixin = {
_pinRegistryJsonGossipKeys: null,
_pinJsonHealWatermark: null,
_reactionSummaryJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._pinRegistryCsvGossipKeys) {
this._pinRegistryCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._pinRegistryJsonGossipKeys) {
this._pinRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipPinRegistryCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipPinRegistryJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._pinRegistryCsvGossipKeys.has(hash)) return false
this._pinRegistryCsvGossipKeys.add(hash)
if (this._pinRegistryCsvGossipKeys.size > 8192) {
const first = this._pinRegistryCsvGossipKeys.values().next().value
if (first) this._pinRegistryCsvGossipKeys.delete(first)
if (this._pinRegistryJsonGossipKeys.has(hash)) return false
this._pinRegistryJsonGossipKeys.add(hash)
if (this._pinRegistryJsonGossipKeys.size > 8192) {
const first = this._pinRegistryJsonGossipKeys.values().next().value
if (first) this._pinRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipReactionSummaryExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipReactionSummaryExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._pinRegistryCsvGossipKeys.has(hash)) return false
this._pinRegistryCsvGossipKeys.add(hash)
if (this._pinRegistryJsonGossipKeys.has(hash)) return false
this._pinRegistryJsonGossipKeys.add(hash)
return true
},
async _healPinRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('pin.csv', {
spanKind: 'pin.csv',
const span = this.log.time('pin.json', {
spanKind: 'pin.json',
guildId: gid,
context: 'heal.pin'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPinCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPinJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listPinRegistryCsvExports(64)
const rows = await this.deliveryReceipts.listPinRegistryJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipPinRegistryCsv(row)) relisted++
if (this._shouldGossipPinRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._pinCsvHealWatermark = watermark
this._pinJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPinCsvCount: rows.length,
bridgeKind: 'pin.csv'
guildPinJsonCount: rows.length,
bridgeKind: 'pin.json'
})
return { relisted, watermark, guildPinCsvCount: rows.length }
return { relisted, watermark, guildPinJsonCount: rows.length }
} catch (err) {
this.log.error('pin.csv error', {
this.log.error('pin.json error', {
guildId: gid,
context: 'heal.pin',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const pinCsvMixin = {
async _healReactionSummaryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('pin.csv', {
spanKind: 'pin.csv',
const span = this.log.time('pin.json', {
spanKind: 'pin.json',
guildId: gid,
context: 'heal.reaction'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPinCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPinJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listReactionSummaryExportCsvExports(64)
const rows = await this.deliveryReceipts.listReactionSummaryExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipReactionSummaryExportCsv(row)) relisted++
if (this._shouldGossipReactionSummaryExportJson(row)) relisted++
}
const watermark = Date.now()
this._reactionSummaryCsvHealWatermark = watermark
this._reactionSummaryJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPinCsvCount: rows.length,
guildPinJsonCount: rows.length,
pinCount: rows[0]?.pinCount || 0,
bridgeKind: 'pin.csv'
bridgeKind: 'pin.json'
})
return { relisted, watermark, pinCount: rows[0]?.pinCount || 0 }
} catch (err) {
this.log.error('pin.csv error', {
this.log.error('pin.json error', {
guildId: gid,
context: 'heal.reaction',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const pinCsvMixin = {
}
}
module.exports = { pinCsvMixin }
module.exports = { pinJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const pollCsvMixin = {
_pollRegistryCsvGossipKeys: null,
_pollCsvHealWatermark: null,
_scheduledMessageCsvHealWatermark: null,
const pollJsonMixin = {
_pollRegistryJsonGossipKeys: null,
_pollJsonHealWatermark: null,
_scheduledMessageJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._pollRegistryCsvGossipKeys) {
this._pollRegistryCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._pollRegistryJsonGossipKeys) {
this._pollRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipPollRegistryCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipPollRegistryJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._pollRegistryCsvGossipKeys.has(hash)) return false
this._pollRegistryCsvGossipKeys.add(hash)
if (this._pollRegistryCsvGossipKeys.size > 8192) {
const first = this._pollRegistryCsvGossipKeys.values().next().value
if (first) this._pollRegistryCsvGossipKeys.delete(first)
if (this._pollRegistryJsonGossipKeys.has(hash)) return false
this._pollRegistryJsonGossipKeys.add(hash)
if (this._pollRegistryJsonGossipKeys.size > 8192) {
const first = this._pollRegistryJsonGossipKeys.values().next().value
if (first) this._pollRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipScheduledMessageExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipScheduledMessageExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._pollRegistryCsvGossipKeys.has(hash)) return false
this._pollRegistryCsvGossipKeys.add(hash)
if (this._pollRegistryJsonGossipKeys.has(hash)) return false
this._pollRegistryJsonGossipKeys.add(hash)
return true
},
async _healPollRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('poll.csv', {
spanKind: 'poll.csv',
const span = this.log.time('poll.json', {
spanKind: 'poll.json',
guildId: gid,
context: 'heal.poll'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPollCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPollJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listPollRegistryCsvExports(64)
const rows = await this.deliveryReceipts.listPollRegistryJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipPollRegistryCsv(row)) relisted++
if (this._shouldGossipPollRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._pollCsvHealWatermark = watermark
this._pollJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPollCsvCount: rows.length,
bridgeKind: 'poll.csv'
guildPollJsonCount: rows.length,
bridgeKind: 'poll.json'
})
return { relisted, watermark, guildPollCsvCount: rows.length }
return { relisted, watermark, guildPollJsonCount: rows.length }
} catch (err) {
this.log.error('poll.csv error', {
this.log.error('poll.json error', {
guildId: gid,
context: 'heal.poll',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const pollCsvMixin = {
async _healScheduledMessageExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('poll.csv', {
spanKind: 'poll.csv',
const span = this.log.time('poll.json', {
spanKind: 'poll.json',
guildId: gid,
context: 'heal.schedule'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPollCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPollJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listScheduledMessageExportCsvExports(64)
const rows = await this.deliveryReceipts.listScheduledMessageExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipScheduledMessageExportCsv(row)) relisted++
if (this._shouldGossipScheduledMessageExportJson(row)) relisted++
}
const watermark = Date.now()
this._scheduledMessageCsvHealWatermark = watermark
this._scheduledMessageJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPollCsvCount: rows.length,
guildPollJsonCount: rows.length,
pollCount: rows[0]?.pollCount || 0,
bridgeKind: 'poll.csv'
bridgeKind: 'poll.json'
})
return { relisted, watermark, pollCount: rows[0]?.pollCount || 0 }
} catch (err) {
this.log.error('poll.csv error', {
this.log.error('poll.json error', {
guildId: gid,
context: 'heal.schedule',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const pollCsvMixin = {
}
}
module.exports = { pollCsvMixin }
module.exports = { pollJsonMixin }
@@ -1,67 +1,67 @@
'use strict'
const presenceCsvMixin = {
_presenceRegistryCsvGossipKeys: null,
_presenceCsvHealWatermark: null,
_readStateExportCsvHealWatermark: null,
const presenceJsonMixin = {
_presenceRegistryJsonGossipKeys: null,
_presenceJsonHealWatermark: null,
_readStateExportJsonHealWatermark: null,
_initPresenceCsvMixinState () {
if (!this._presenceRegistryCsvGossipKeys) {
this._presenceRegistryCsvGossipKeys = new Set()
_initPresenceJsonMixinState () {
if (!this._presenceRegistryJsonGossipKeys) {
this._presenceRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipPresenceRegistryCsv (slice) {
this._initPresenceCsvMixinState()
_shouldGossipPresenceRegistryJson (slice) {
this._initPresenceJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._presenceRegistryCsvGossipKeys.has(hash)) return false
this._presenceRegistryCsvGossipKeys.add(hash)
if (this._presenceRegistryCsvGossipKeys.size > 8192) {
const first = this._presenceRegistryCsvGossipKeys.values().next().value
if (first) this._presenceRegistryCsvGossipKeys.delete(first)
if (this._presenceRegistryJsonGossipKeys.has(hash)) return false
this._presenceRegistryJsonGossipKeys.add(hash)
if (this._presenceRegistryJsonGossipKeys.size > 8192) {
const first = this._presenceRegistryJsonGossipKeys.values().next().value
if (first) this._presenceRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipReadStateExportCsv (slice) {
this._initPresenceCsvMixinState()
_shouldGossipReadStateExportJson (slice) {
this._initPresenceJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._presenceRegistryCsvGossipKeys.has(hash)) return false
this._presenceRegistryCsvGossipKeys.add(hash)
if (this._presenceRegistryJsonGossipKeys.has(hash)) return false
this._presenceRegistryJsonGossipKeys.add(hash)
return true
},
async _healPresenceActivityExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('presence.csv', {
spanKind: 'presence.csv',
const span = this.log.time('presence.json', {
spanKind: 'presence.json',
guildId: gid,
context: 'heal.presence'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPresenceCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPresenceJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listPresenceActivityCsvExports(64)
const rows = await this.deliveryReceipts.listPresenceActivityJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipPresenceRegistryCsv(row)) relisted++
if (this._shouldGossipPresenceRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._presenceCsvHealWatermark = watermark
this._presenceJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPresenceCsvCount: rows.length,
bridgeKind: 'presence.csv'
guildPresenceJsonCount: rows.length,
bridgeKind: 'presence.json'
})
return { relisted, watermark, guildPresenceCsvCount: rows.length }
return { relisted, watermark, guildPresenceJsonCount: rows.length }
} catch (err) {
this.log.error('presence.csv error', {
this.log.error('presence.json error', {
guildId: gid,
context: 'heal.presence',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const presenceCsvMixin = {
async _healReadStateExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('presence.csv', {
spanKind: 'presence.csv',
const span = this.log.time('presence.json', {
spanKind: 'presence.json',
guildId: gid,
context: 'heal.read-state'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildPresenceCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildPresenceJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listReadStateExportCsvExports(64)
const rows = await this.deliveryReceipts.listReadStateExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipReadStateExportCsv(row)) relisted++
if (this._shouldGossipReadStateExportJson(row)) relisted++
}
const watermark = Date.now()
this._readStateExportCsvHealWatermark = watermark
this._readStateExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildPresenceCsvCount: rows.length,
guildPresenceJsonCount: rows.length,
presenceCount: rows[0]?.presenceCount || 0,
bridgeKind: 'presence.csv'
bridgeKind: 'presence.json'
})
return { relisted, watermark, presenceCount: rows[0]?.presenceCount || 0 }
} catch (err) {
this.log.error('presence.csv error', {
this.log.error('presence.json error', {
guildId: gid,
context: 'heal.read-state',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const presenceCsvMixin = {
}
}
module.exports = { presenceCsvMixin }
module.exports = { presenceJsonMixin }
+32 -32
View File
@@ -1,42 +1,42 @@
'use strict'
const relayCsvMixin = {
_digestRelayHandoffCsvGossipKeys: null,
_relayCsvHealWatermark: null,
const relayJsonMixin = {
_digestRelayHandoffJsonGossipKeys: null,
_relayJsonHealWatermark: null,
_archivePeerExportHealWatermark: null,
_initRelayCsvMixinState () {
if (!this._digestRelayHandoffCsvGossipKeys) {
this._digestRelayHandoffCsvGossipKeys = new Set()
_initRelayJsonMixinState () {
if (!this._digestRelayHandoffJsonGossipKeys) {
this._digestRelayHandoffJsonGossipKeys = new Set()
}
},
_shouldGossipDigestRelayHandoffCsv (slice) {
this._initRelayCsvMixinState()
_shouldGossipDigestRelayHandoffJson (slice) {
this._initRelayJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._digestRelayHandoffCsvGossipKeys.has(hash)) return false
this._digestRelayHandoffCsvGossipKeys.add(hash)
if (this._digestRelayHandoffCsvGossipKeys.size > 8192) {
const first = this._digestRelayHandoffCsvGossipKeys.values().next().value
if (first) this._digestRelayHandoffCsvGossipKeys.delete(first)
if (this._digestRelayHandoffJsonGossipKeys.has(hash)) return false
this._digestRelayHandoffJsonGossipKeys.add(hash)
if (this._digestRelayHandoffJsonGossipKeys.size > 8192) {
const first = this._digestRelayHandoffJsonGossipKeys.values().next().value
if (first) this._digestRelayHandoffJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipArchivePeerExportCsv (slice) {
this._initRelayCsvMixinState()
_shouldGossipArchivePeerExportJson (slice) {
this._initRelayJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `archive:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._digestRelayHandoffCsvGossipKeys.has(hash)) return false
this._digestRelayHandoffCsvGossipKeys.add(hash)
if (this._digestRelayHandoffJsonGossipKeys.has(hash)) return false
this._digestRelayHandoffJsonGossipKeys.add(hash)
return true
},
async _healDigestRelayHandoffCsvCursorOnPartition (guildId) {
async _healDigestRelayHandoffJsonCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('relay.csv', {
spanKind: 'relay.csv',
const span = this.log.time('relay.json', {
spanKind: 'relay.json',
guildId: gid,
context: 'heal.handoff'
})
@@ -46,22 +46,22 @@ const relayCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listDigestRelayHandoffCsvExports(64)
const rows = await this.deliveryReceipts.listDigestRelayHandoffJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipDigestRelayHandoffCsv(row)) relisted++
if (this._shouldGossipDigestRelayHandoffJson(row)) relisted++
}
const watermark = Date.now()
this._relayCsvHealWatermark = watermark
this._relayJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildRelayHandoffCount: rows.length,
bridgeKind: 'relay.csv'
bridgeKind: 'relay.json'
})
return { relisted, watermark, guildRelayHandoffCount: rows.length }
} catch (err) {
this.log.error('relay.csv error', {
this.log.error('relay.json error', {
guildId: gid,
context: 'heal.handoff',
error: err?.message || String(err)
@@ -73,8 +73,8 @@ const relayCsvMixin = {
async _healArchivePeerExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('relay.csv', {
spanKind: 'relay.csv',
const span = this.log.time('relay.json', {
spanKind: 'relay.json',
guildId: gid,
context: 'heal.archive'
})
@@ -84,10 +84,10 @@ const relayCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listArchivePeerExportCsvExports(64)
const rows = await this.deliveryReceipts.listArchivePeerExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipArchivePeerExportCsv(row)) relisted++
if (this._shouldGossipArchivePeerExportJson(row)) relisted++
}
const watermark = Date.now()
this._archivePeerExportHealWatermark = watermark
@@ -96,11 +96,11 @@ const relayCsvMixin = {
watermark,
guildRelayHandoffCount: rows.length,
entryCount: rows[0]?.peerCount || 0,
bridgeKind: 'relay.csv'
bridgeKind: 'relay.json'
})
return { relisted, watermark, entryCount: rows[0]?.peerCount || 0 }
} catch (err) {
this.log.error('relay.csv error', {
this.log.error('relay.json error', {
guildId: gid,
context: 'heal.archive',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const relayCsvMixin = {
}
}
module.exports = { relayCsvMixin }
module.exports = { relayJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const screenCsvMixin = {
_threadRegistryCsvGossipKeys: null,
_screenCsvHealWatermark: null,
_soundboardRegistryExportCsvHealWatermark: null,
const screenJsonMixin = {
_threadRegistryJsonGossipKeys: null,
_screenJsonHealWatermark: null,
_soundboardRegistryExportJsonHealWatermark: null,
_initScreenCsvMixinState () {
if (!this._threadRegistryCsvGossipKeys) {
this._threadRegistryCsvGossipKeys = new Set()
_initScreenJsonMixinState () {
if (!this._threadRegistryJsonGossipKeys) {
this._threadRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipScreenRegistryCsv (slice) {
this._initScreenCsvMixinState()
_shouldGossipScreenRegistryJson (slice) {
this._initScreenJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryCsvGossipKeys.size > 8192) {
const first = this._threadRegistryCsvGossipKeys.values().next().value
if (first) this._threadRegistryCsvGossipKeys.delete(first)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.size > 8192) {
const first = this._threadRegistryJsonGossipKeys.values().next().value
if (first) this._threadRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipSoundboardRegistryExportCsv (slice) {
this._initScreenCsvMixinState()
_shouldGossipSoundboardRegistryExportJson (slice) {
this._initScreenJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
return true
},
async _healScreenShareExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('screen.csv', {
spanKind: 'screen.csv',
const span = this.log.time('screen.json', {
spanKind: 'screen.json',
guildId: gid,
context: 'heal.thread'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildScreenCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildScreenJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listScreenShareCsvExports(64)
const rows = await this.deliveryReceipts.listScreenShareJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipScreenRegistryCsv(row)) relisted++
if (this._shouldGossipScreenRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._screenCsvHealWatermark = watermark
this._screenJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildScreenCsvCount: rows.length,
bridgeKind: 'screen.csv'
guildScreenJsonCount: rows.length,
bridgeKind: 'screen.json'
})
return { relisted, watermark, guildScreenCsvCount: rows.length }
return { relisted, watermark, guildScreenJsonCount: rows.length }
} catch (err) {
this.log.error('screen.csv error', {
this.log.error('screen.json error', {
guildId: gid,
context: 'heal.thread',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const screenCsvMixin = {
async _healSoundboardRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('screen.csv', {
spanKind: 'screen.csv',
const span = this.log.time('screen.json', {
spanKind: 'screen.json',
guildId: gid,
context: 'heal.forum'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildScreenCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildScreenJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listSoundboardRegistryExportCsvExports(64)
const rows = await this.deliveryReceipts.listSoundboardRegistryExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipSoundboardRegistryExportCsv(row)) relisted++
if (this._shouldGossipSoundboardRegistryExportJson(row)) relisted++
}
const watermark = Date.now()
this._soundboardRegistryExportCsvHealWatermark = watermark
this._soundboardRegistryExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildScreenCsvCount: rows.length,
guildScreenJsonCount: rows.length,
shareCount: rows[0]?.shareCount || 0,
bridgeKind: 'screen.csv'
bridgeKind: 'screen.json'
})
return { relisted, watermark, shareCount: rows[0]?.shareCount || 0 }
} catch (err) {
this.log.error('screen.csv error', {
this.log.error('screen.json error', {
guildId: gid,
context: 'heal.forum',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const screenCsvMixin = {
}
}
module.exports = { screenCsvMixin }
module.exports = { screenJsonMixin }
+114
View File
@@ -0,0 +1,114 @@
'use strict'
const sessionJsonMixin = {
_sessionRegistryJsonGossipKeys: null,
_sessionJsonHealWatermark: null,
_avatarDecorationExportJsonHealWatermark: null,
_initSessionJsonMixinState () {
if (!this._sessionRegistryJsonGossipKeys) {
this._sessionRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipSessionActivityRegistryJson (slice) {
this._initSessionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._sessionRegistryJsonGossipKeys.has(hash)) return false
this._sessionRegistryJsonGossipKeys.add(hash)
if (this._sessionRegistryJsonGossipKeys.size > 8192) {
const first = this._sessionRegistryJsonGossipKeys.values().next().value
if (first) this._sessionRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipAvatarDecorationExportJson (slice) {
this._initSessionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._sessionRegistryJsonGossipKeys.has(hash)) return false
this._sessionRegistryJsonGossipKeys.add(hash)
return true
},
async _healSessionActivityExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('session.json', {
spanKind: 'session.json',
guildId: gid,
context: 'heal.session'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildSessionJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listSessionActivityJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipSessionActivityRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._sessionJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildSessionJsonCount: rows.length,
bridgeKind: 'session.json'
})
return { relisted, watermark, guildSessionJsonCount: rows.length }
} catch (err) {
this.log.error('session.json error', {
guildId: gid,
context: 'heal.session',
error: err?.message || String(err)
})
span.fail(err)
return { relisted: 0, error: err?.message || String(err) }
}
},
async _healAvatarDecorationExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('session.json', {
spanKind: 'session.json',
guildId: gid,
context: 'heal.avatar-decoration'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildSessionJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listAvatarDecorationExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipAvatarDecorationExportJson(row)) relisted++
}
const watermark = Date.now()
this._avatarDecorationExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildSessionJsonCount: rows.length,
inviteCount: rows[0]?.decorationCount || 0,
bridgeKind: 'session.json'
})
return { relisted, watermark, decorationCount: rows[0]?.decorationCount || 0 }
} catch (err) {
this.log.error('session.json error', {
guildId: gid,
context: 'heal.avatar-decoration',
error: err?.message || String(err)
})
span.fail(err)
return { relisted: 0, error: err?.message || String(err) }
}
}
}
module.exports = { sessionJsonMixin }
+33 -33
View File
@@ -1,42 +1,42 @@
'use strict'
const slashCsvMixin = {
_slashRegistryCsvGossipKeys: null,
_slashCsvHealWatermark: null,
_slashInvokeAuditCsvHealWatermark: null,
const slashJsonMixin = {
_slashRegistryJsonGossipKeys: null,
_slashJsonHealWatermark: null,
_slashInvokeAuditJsonHealWatermark: null,
_initSlashCsvMixinState () {
if (!this._slashRegistryCsvGossipKeys) {
this._slashRegistryCsvGossipKeys = new Set()
_initSlashJsonMixinState () {
if (!this._slashRegistryJsonGossipKeys) {
this._slashRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipSlashRegistryCsv (slice) {
this._initSlashCsvMixinState()
_shouldGossipSlashRegistryJson (slice) {
this._initSlashJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._slashRegistryCsvGossipKeys.has(hash)) return false
this._slashRegistryCsvGossipKeys.add(hash)
if (this._slashRegistryCsvGossipKeys.size > 8192) {
const first = this._slashRegistryCsvGossipKeys.values().next().value
if (first) this._slashRegistryCsvGossipKeys.delete(first)
if (this._slashRegistryJsonGossipKeys.has(hash)) return false
this._slashRegistryJsonGossipKeys.add(hash)
if (this._slashRegistryJsonGossipKeys.size > 8192) {
const first = this._slashRegistryJsonGossipKeys.values().next().value
if (first) this._slashRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipSlashInvokeAuditExportCsv (slice) {
this._initSlashCsvMixinState()
_shouldGossipSlashInvokeAuditExportJson (slice) {
this._initSlashJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `invoke:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._slashRegistryCsvGossipKeys.has(hash)) return false
this._slashRegistryCsvGossipKeys.add(hash)
if (this._slashRegistryJsonGossipKeys.has(hash)) return false
this._slashRegistryJsonGossipKeys.add(hash)
return true
},
async _healSlashRegistryExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('slash.csv', {
spanKind: 'slash.csv',
const span = this.log.time('slash.json', {
spanKind: 'slash.json',
guildId: gid,
context: 'heal.registry'
})
@@ -46,22 +46,22 @@ const slashCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listSlashRegistryCsvExports(64)
const rows = await this.deliveryReceipts.listSlashRegistryJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipSlashRegistryCsv(row)) relisted++
if (this._shouldGossipSlashRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._slashCsvHealWatermark = watermark
this._slashJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildSlashRegistryCount: rows.length,
bridgeKind: 'slash.csv'
bridgeKind: 'slash.json'
})
return { relisted, watermark, guildSlashRegistryCount: rows.length }
} catch (err) {
this.log.error('slash.csv error', {
this.log.error('slash.json error', {
guildId: gid,
context: 'heal.registry',
error: err?.message || String(err)
@@ -73,8 +73,8 @@ const slashCsvMixin = {
async _healSlashInvokeAuditExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('slash.csv', {
spanKind: 'slash.csv',
const span = this.log.time('slash.json', {
spanKind: 'slash.json',
guildId: gid,
context: 'heal.invoke'
})
@@ -84,23 +84,23 @@ const slashCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listSlashInvokeAuditExportCsvExports(64)
const rows = await this.deliveryReceipts.listSlashInvokeAuditExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipSlashInvokeAuditExportCsv(row)) relisted++
if (this._shouldGossipSlashInvokeAuditExportJson(row)) relisted++
}
const watermark = Date.now()
this._slashInvokeAuditCsvHealWatermark = watermark
this._slashInvokeAuditJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildSlashRegistryCount: rows.length,
invokeCount: rows[0]?.invokeCount || 0,
bridgeKind: 'slash.csv'
bridgeKind: 'slash.json'
})
return { relisted, watermark, invokeCount: rows[0]?.invokeCount || 0 }
} catch (err) {
this.log.error('slash.csv error', {
this.log.error('slash.json error', {
guildId: gid,
context: 'heal.invoke',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const slashCsvMixin = {
}
}
module.exports = { slashCsvMixin }
module.exports = { slashJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const stageCsvMixin = {
_threadRegistryCsvGossipKeys: null,
_stageCsvHealWatermark: null,
_guildEventExportCsvHealWatermark: null,
const stageJsonMixin = {
_threadRegistryJsonGossipKeys: null,
_stageJsonHealWatermark: null,
_guildEventExportJsonHealWatermark: null,
_initStageCsvMixinState () {
if (!this._threadRegistryCsvGossipKeys) {
this._threadRegistryCsvGossipKeys = new Set()
_initStageJsonMixinState () {
if (!this._threadRegistryJsonGossipKeys) {
this._threadRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipStageRegistryCsv (slice) {
this._initStageCsvMixinState()
_shouldGossipStageRegistryJson (slice) {
this._initStageJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryCsvGossipKeys.size > 8192) {
const first = this._threadRegistryCsvGossipKeys.values().next().value
if (first) this._threadRegistryCsvGossipKeys.delete(first)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.size > 8192) {
const first = this._threadRegistryJsonGossipKeys.values().next().value
if (first) this._threadRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipGuildEventExportCsv (slice) {
this._initStageCsvMixinState()
_shouldGossipGuildEventExportJson (slice) {
this._initStageJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
return true
},
async _healStageInstanceExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('stage.csv', {
spanKind: 'stage.csv',
const span = this.log.time('stage.json', {
spanKind: 'stage.json',
guildId: gid,
context: 'heal.thread'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildStageCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildStageJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listStageInstanceCsvExports(64)
const rows = await this.deliveryReceipts.listStageInstanceJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipStageRegistryCsv(row)) relisted++
if (this._shouldGossipStageRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._stageCsvHealWatermark = watermark
this._stageJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildStageCsvCount: rows.length,
bridgeKind: 'stage.csv'
guildStageJsonCount: rows.length,
bridgeKind: 'stage.json'
})
return { relisted, watermark, guildStageCsvCount: rows.length }
return { relisted, watermark, guildStageJsonCount: rows.length }
} catch (err) {
this.log.error('stage.csv error', {
this.log.error('stage.json error', {
guildId: gid,
context: 'heal.thread',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const stageCsvMixin = {
async _healGuildEventExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('stage.csv', {
spanKind: 'stage.csv',
const span = this.log.time('stage.json', {
spanKind: 'stage.json',
guildId: gid,
context: 'heal.forum'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildStageCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildStageJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listGuildEventExportCsvExports(64)
const rows = await this.deliveryReceipts.listGuildEventExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipGuildEventExportCsv(row)) relisted++
if (this._shouldGossipGuildEventExportJson(row)) relisted++
}
const watermark = Date.now()
this._guildEventExportCsvHealWatermark = watermark
this._guildEventExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildStageCsvCount: rows.length,
guildStageJsonCount: rows.length,
stageCount: rows[0]?.stageCount || 0,
bridgeKind: 'stage.csv'
bridgeKind: 'stage.json'
})
return { relisted, watermark, stageCount: rows[0]?.stageCount || 0 }
} catch (err) {
this.log.error('stage.csv error', {
this.log.error('stage.json error', {
guildId: gid,
context: 'heal.forum',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const stageCsvMixin = {
}
}
module.exports = { stageCsvMixin }
module.exports = { stageJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const statusCsvMixin = {
_statusRegistryCsvGossipKeys: null,
_statusCsvHealWatermark: null,
_guildWidgetExportCsvHealWatermark: null,
const statusJsonMixin = {
_statusRegistryJsonGossipKeys: null,
_statusJsonHealWatermark: null,
_guildWidgetExportJsonHealWatermark: null,
_initStatusCsvMixinState () {
if (!this._statusRegistryCsvGossipKeys) {
this._statusRegistryCsvGossipKeys = new Set()
_initStatusJsonMixinState () {
if (!this._statusRegistryJsonGossipKeys) {
this._statusRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipCustomStatusRegistryCsv (slice) {
this._initStatusCsvMixinState()
_shouldGossipCustomStatusRegistryJson (slice) {
this._initStatusJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._statusRegistryCsvGossipKeys.has(hash)) return false
this._statusRegistryCsvGossipKeys.add(hash)
if (this._statusRegistryCsvGossipKeys.size > 8192) {
const first = this._statusRegistryCsvGossipKeys.values().next().value
if (first) this._statusRegistryCsvGossipKeys.delete(first)
if (this._statusRegistryJsonGossipKeys.has(hash)) return false
this._statusRegistryJsonGossipKeys.add(hash)
if (this._statusRegistryJsonGossipKeys.size > 8192) {
const first = this._statusRegistryJsonGossipKeys.values().next().value
if (first) this._statusRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipGuildWidgetExportCsv (slice) {
this._initStatusCsvMixinState()
_shouldGossipGuildWidgetExportJson (slice) {
this._initStatusJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._statusRegistryCsvGossipKeys.has(hash)) return false
this._statusRegistryCsvGossipKeys.add(hash)
if (this._statusRegistryJsonGossipKeys.has(hash)) return false
this._statusRegistryJsonGossipKeys.add(hash)
return true
},
async _healCustomStatusExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('status.csv', {
spanKind: 'status.csv',
const span = this.log.time('status.json', {
spanKind: 'status.json',
guildId: gid,
context: 'heal.status'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildStatusCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildStatusJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listCustomStatusCsvExports(64)
const rows = await this.deliveryReceipts.listCustomStatusJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipCustomStatusRegistryCsv(row)) relisted++
if (this._shouldGossipCustomStatusRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._statusCsvHealWatermark = watermark
this._statusJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildStatusCsvCount: rows.length,
bridgeKind: 'status.csv'
guildStatusJsonCount: rows.length,
bridgeKind: 'status.json'
})
return { relisted, watermark, guildStatusCsvCount: rows.length }
return { relisted, watermark, guildStatusJsonCount: rows.length }
} catch (err) {
this.log.error('status.csv error', {
this.log.error('status.json error', {
guildId: gid,
context: 'heal.status',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const statusCsvMixin = {
async _healGuildWidgetExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('status.csv', {
spanKind: 'status.csv',
const span = this.log.time('status.json', {
spanKind: 'status.json',
guildId: gid,
context: 'heal.guild-widget'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildStatusCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildStatusJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listGuildWidgetExportCsvExports(64)
const rows = await this.deliveryReceipts.listGuildWidgetExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipGuildWidgetExportCsv(row)) relisted++
if (this._shouldGossipGuildWidgetExportJson(row)) relisted++
}
const watermark = Date.now()
this._guildWidgetExportCsvHealWatermark = watermark
this._guildWidgetExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildStatusCsvCount: rows.length,
guildStatusJsonCount: rows.length,
statusCount: rows[0]?.statusCount || 0,
bridgeKind: 'status.csv'
bridgeKind: 'status.json'
})
return { relisted, watermark, statusCount: rows[0]?.statusCount || 0 }
} catch (err) {
this.log.error('status.csv error', {
this.log.error('status.json error', {
guildId: gid,
context: 'heal.guild-widget',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const statusCsvMixin = {
}
}
module.exports = { statusCsvMixin }
module.exports = { statusJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const threadCsvMixin = {
_threadRegistryCsvGossipKeys: null,
_threadCsvHealWatermark: null,
_forumTagExportCsvHealWatermark: null,
const threadJsonMixin = {
_threadRegistryJsonGossipKeys: null,
_threadJsonHealWatermark: null,
_forumTagExportJsonHealWatermark: null,
_initPermissionCsvMixinState () {
if (!this._threadRegistryCsvGossipKeys) {
this._threadRegistryCsvGossipKeys = new Set()
_initPermissionJsonMixinState () {
if (!this._threadRegistryJsonGossipKeys) {
this._threadRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipThreadRegistryCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipThreadRegistryJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryCsvGossipKeys.size > 8192) {
const first = this._threadRegistryCsvGossipKeys.values().next().value
if (first) this._threadRegistryCsvGossipKeys.delete(first)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.size > 8192) {
const first = this._threadRegistryJsonGossipKeys.values().next().value
if (first) this._threadRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipForumTagExportCsv (slice) {
this._initPermissionCsvMixinState()
_shouldGossipForumTagExportJson (slice) {
this._initPermissionJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
return true
},
async _healThreadArchiveExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('thread.csv', {
spanKind: 'thread.csv',
const span = this.log.time('thread.json', {
spanKind: 'thread.json',
guildId: gid,
context: 'heal.thread'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildThreadCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildThreadJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listThreadArchiveCsvExports(64)
const rows = await this.deliveryReceipts.listThreadArchiveJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipThreadRegistryCsv(row)) relisted++
if (this._shouldGossipThreadRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._threadCsvHealWatermark = watermark
this._threadJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildThreadCsvCount: rows.length,
bridgeKind: 'thread.csv'
guildThreadJsonCount: rows.length,
bridgeKind: 'thread.json'
})
return { relisted, watermark, guildThreadCsvCount: rows.length }
return { relisted, watermark, guildThreadJsonCount: rows.length }
} catch (err) {
this.log.error('thread.csv error', {
this.log.error('thread.json error', {
guildId: gid,
context: 'heal.thread',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const threadCsvMixin = {
async _healForumTagExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('thread.csv', {
spanKind: 'thread.csv',
const span = this.log.time('thread.json', {
spanKind: 'thread.json',
guildId: gid,
context: 'heal.forum'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildThreadCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildThreadJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listForumTagExportCsvExports(64)
const rows = await this.deliveryReceipts.listForumTagExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipForumTagExportCsv(row)) relisted++
if (this._shouldGossipForumTagExportJson(row)) relisted++
}
const watermark = Date.now()
this._forumTagExportCsvHealWatermark = watermark
this._forumTagExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildThreadCsvCount: rows.length,
guildThreadJsonCount: rows.length,
threadCount: rows[0]?.threadCount || 0,
bridgeKind: 'thread.csv'
bridgeKind: 'thread.json'
})
return { relisted, watermark, threadCount: rows[0]?.threadCount || 0 }
} catch (err) {
this.log.error('thread.csv error', {
this.log.error('thread.json error', {
guildId: gid,
context: 'heal.forum',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const threadCsvMixin = {
}
}
module.exports = { threadCsvMixin }
module.exports = { threadJsonMixin }
+38 -38
View File
@@ -1,67 +1,67 @@
'use strict'
const voiceCsvMixin = {
_threadRegistryCsvGossipKeys: null,
_voiceCsvHealWatermark: null,
_boostLedgerExportCsvHealWatermark: null,
const voiceJsonMixin = {
_threadRegistryJsonGossipKeys: null,
_voiceJsonHealWatermark: null,
_boostLedgerExportJsonHealWatermark: null,
_initVoiceCsvMixinState () {
if (!this._threadRegistryCsvGossipKeys) {
this._threadRegistryCsvGossipKeys = new Set()
_initVoiceJsonMixinState () {
if (!this._threadRegistryJsonGossipKeys) {
this._threadRegistryJsonGossipKeys = new Set()
}
},
_shouldGossipVoiceRegistryCsv (slice) {
this._initVoiceCsvMixinState()
_shouldGossipVoiceRegistryJson (slice) {
this._initVoiceJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryCsvGossipKeys.size > 8192) {
const first = this._threadRegistryCsvGossipKeys.values().next().value
if (first) this._threadRegistryCsvGossipKeys.delete(first)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.size > 8192) {
const first = this._threadRegistryJsonGossipKeys.values().next().value
if (first) this._threadRegistryJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipBoostLedgerExportCsv (slice) {
this._initVoiceCsvMixinState()
_shouldGossipBoostLedgerExportJson (slice) {
this._initVoiceJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `effective:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._threadRegistryCsvGossipKeys.has(hash)) return false
this._threadRegistryCsvGossipKeys.add(hash)
if (this._threadRegistryJsonGossipKeys.has(hash)) return false
this._threadRegistryJsonGossipKeys.add(hash)
return true
},
async _healVoiceStateExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('voice.csv', {
spanKind: 'voice.csv',
const span = this.log.time('voice.json', {
spanKind: 'voice.json',
guildId: gid,
context: 'heal.thread'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildVoiceCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildVoiceJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listVoiceStateCsvExports(64)
const rows = await this.deliveryReceipts.listVoiceStateJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipVoiceRegistryCsv(row)) relisted++
if (this._shouldGossipVoiceRegistryJson(row)) relisted++
}
const watermark = Date.now()
this._voiceCsvHealWatermark = watermark
this._voiceJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildVoiceCsvCount: rows.length,
bridgeKind: 'voice.csv'
guildVoiceJsonCount: rows.length,
bridgeKind: 'voice.json'
})
return { relisted, watermark, guildVoiceCsvCount: rows.length }
return { relisted, watermark, guildVoiceJsonCount: rows.length }
} catch (err) {
this.log.error('voice.csv error', {
this.log.error('voice.json error', {
guildId: gid,
context: 'heal.thread',
error: err?.message || String(err)
@@ -73,34 +73,34 @@ const voiceCsvMixin = {
async _healBoostLedgerExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('voice.csv', {
spanKind: 'voice.csv',
const span = this.log.time('voice.json', {
spanKind: 'voice.json',
guildId: gid,
context: 'heal.forum'
})
try {
if (!gid || !this.deliveryReceipts) {
span.end({ relisted: 0, skipped: true, guildVoiceCsvCount: 0 })
span.end({ relisted: 0, skipped: true, guildVoiceJsonCount: 0 })
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listBoostLedgerExportCsvExports(64)
const rows = await this.deliveryReceipts.listBoostLedgerExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipBoostLedgerExportCsv(row)) relisted++
if (this._shouldGossipBoostLedgerExportJson(row)) relisted++
}
const watermark = Date.now()
this._boostLedgerExportCsvHealWatermark = watermark
this._boostLedgerExportJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildVoiceCsvCount: rows.length,
guildVoiceJsonCount: rows.length,
voiceCount: rows[0]?.voiceCount || 0,
bridgeKind: 'voice.csv'
bridgeKind: 'voice.json'
})
return { relisted, watermark, voiceCount: rows[0]?.voiceCount || 0 }
} catch (err) {
this.log.error('voice.csv error', {
this.log.error('voice.json error', {
guildId: gid,
context: 'heal.forum',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const voiceCsvMixin = {
}
}
module.exports = { voiceCsvMixin }
module.exports = { voiceJsonMixin }
+31 -31
View File
@@ -1,42 +1,42 @@
'use strict'
const workerCsvMixin = {
_workerReleaseCsvGossipKeys: null,
_workerCsvHealWatermark: null,
const workerJsonMixin = {
_workerReleaseJsonGossipKeys: null,
_workerJsonHealWatermark: null,
_integrationManifestHealWatermark: null,
_initWorkerCsvMixinState () {
if (!this._workerReleaseCsvGossipKeys) {
this._workerReleaseCsvGossipKeys = new Set()
_initWorkerJsonMixinState () {
if (!this._workerReleaseJsonGossipKeys) {
this._workerReleaseJsonGossipKeys = new Set()
}
},
_shouldGossipWorkerReleaseCsv (slice) {
this._initWorkerCsvMixinState()
_shouldGossipWorkerReleaseJson (slice) {
this._initWorkerJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._workerReleaseCsvGossipKeys.has(hash)) return false
this._workerReleaseCsvGossipKeys.add(hash)
if (this._workerReleaseCsvGossipKeys.size > 8192) {
const first = this._workerReleaseCsvGossipKeys.values().next().value
if (first) this._workerReleaseCsvGossipKeys.delete(first)
if (this._workerReleaseJsonGossipKeys.has(hash)) return false
this._workerReleaseJsonGossipKeys.add(hash)
if (this._workerReleaseJsonGossipKeys.size > 8192) {
const first = this._workerReleaseJsonGossipKeys.values().next().value
if (first) this._workerReleaseJsonGossipKeys.delete(first)
}
return true
},
_shouldGossipIntegrationManifestExportCsv (slice) {
this._initWorkerCsvMixinState()
_shouldGossipIntegrationManifestExportJson (slice) {
this._initWorkerJsonMixinState()
if (!slice?.guildId || !slice?.signature) return true
const hash = `manifest:${slice.guildId}:${slice.exportedAt || 0}:${slice.signature}`
if (this._workerReleaseCsvGossipKeys.has(hash)) return false
this._workerReleaseCsvGossipKeys.add(hash)
if (this._workerReleaseJsonGossipKeys.has(hash)) return false
this._workerReleaseJsonGossipKeys.add(hash)
return true
},
async _healWorkerReleaseExportCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('worker.csv', {
spanKind: 'worker.csv',
const span = this.log.time('worker.json', {
spanKind: 'worker.json',
guildId: gid,
context: 'heal.release'
})
@@ -46,22 +46,22 @@ const workerCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listWorkerReleaseCsvExports(64)
const rows = await this.deliveryReceipts.listWorkerReleaseJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipWorkerReleaseCsv(row)) relisted++
if (this._shouldGossipWorkerReleaseJson(row)) relisted++
}
const watermark = Date.now()
this._workerCsvHealWatermark = watermark
this._workerJsonHealWatermark = watermark
span.end({
relisted,
watermark,
guildWorkerReleaseCount: rows.length,
bridgeKind: 'worker.csv'
bridgeKind: 'worker.json'
})
return { relisted, watermark, guildWorkerReleaseCount: rows.length }
} catch (err) {
this.log.error('worker.csv error', {
this.log.error('worker.json error', {
guildId: gid,
context: 'heal.release',
error: err?.message || String(err)
@@ -73,8 +73,8 @@ const workerCsvMixin = {
async _healIntegrationManifestCursorOnPartition (guildId) {
const gid = guildId || this.guild?.guild?.id || null
const span = this.log.time('worker.csv', {
spanKind: 'worker.csv',
const span = this.log.time('worker.json', {
spanKind: 'worker.json',
guildId: gid,
context: 'heal.manifest'
})
@@ -84,10 +84,10 @@ const workerCsvMixin = {
return { relisted: 0, skipped: true }
}
await this._initDeliveryReceipts(gid)
const rows = await this.deliveryReceipts.listIntegrationManifestExportCsvExports(64)
const rows = await this.deliveryReceipts.listIntegrationManifestExportJsonExports(64)
let relisted = 0
for (const row of rows) {
if (this._shouldGossipIntegrationManifestExportCsv(row)) relisted++
if (this._shouldGossipIntegrationManifestExportJson(row)) relisted++
}
const watermark = Date.now()
this._integrationManifestHealWatermark = watermark
@@ -96,11 +96,11 @@ const workerCsvMixin = {
watermark,
guildWorkerReleaseCount: rows.length,
templateCount: rows[0]?.templateCount || 0,
bridgeKind: 'worker.csv'
bridgeKind: 'worker.json'
})
return { relisted, watermark, templateCount: rows[0]?.templateCount || 0 }
} catch (err) {
this.log.error('worker.csv error', {
this.log.error('worker.json error', {
guildId: gid,
context: 'heal.manifest',
error: err?.message || String(err)
@@ -111,4 +111,4 @@ const workerCsvMixin = {
}
}
module.exports = { workerCsvMixin }
module.exports = { workerJsonMixin }