Files
peardata/server/services/subscriptions.js
T
Raven Scott 1d902a89b0
CI / test (push) Successful in 1m1s
Release rolling / release (push) Successful in 7m25s
Experimental CPU Optimize Techniques
2026-07-21 11:58:29 -04:00

105 lines
2.6 KiB
JavaScript

/**
* Per-session metric / anomaly push subscriptions.
*/
import { Pushes } from '../../shared/protocol.js'
import { peers } from '../core/peer-registry.js'
/**
* @param {import('../rpc/session.js').PeerSession} session
* @param {{ charts: string[], intervalMs: number }} opts
*/
export function subscribeMetrics(session, opts) {
const charts = opts.charts?.includes('*') ? ['*'] : opts.charts || ['*']
session.state.set('metricSub', {
charts,
intervalMs: opts.intervalMs || 1000,
})
return { success: true, charts, intervalMs: opts.intervalMs || 1000 }
}
/**
* @param {import('../rpc/session.js').PeerSession} session
*/
export function unsubscribeMetrics(session) {
session.state.delete('metricSub')
return { success: true }
}
/**
* @param {import('../rpc/session.js').PeerSession} session
*/
export function subscribeAnomalies(session) {
session.state.set('anomalySub', true)
return { success: true }
}
/**
* @param {import('../rpc/session.js').PeerSession} session
*/
export function unsubscribeAnomalies(session) {
session.state.delete('anomalySub')
return { success: true }
}
/**
* Fan-out a metric batch to subscribed peers (throttled per session preference).
* @param {Array<{ chart: string, context: string, ts: number, values: object }>} batch
*/
export function broadcastMetrics(batch) {
const list = peers.list()
if (!list.length) return
for (const session of list) {
const sub = session.state.get('metricSub')
if (!sub || session.closed) continue
const filtered =
sub.charts.includes('*')
? batch
: batch.filter((s) => sub.charts.includes(s.chart) || sub.charts.includes(s.context))
if (!filtered.length) continue
// simple throttle
const last = session.state.get('metricSubLast') || 0
const now = Date.now()
if (now - last < (sub.intervalMs || 1000) - 50) continue
session.state.set('metricSubLast', now)
try {
session.push(Pushes.metrics, { samples: filtered })
} catch {
// ignore dead peers
}
}
}
/**
* @param {object} anomaly
*/
export function broadcastAnomaly(anomaly) {
const list = peers.list()
if (!list.length) return
for (const session of list) {
if (!session.state.get('anomalySub') || session.closed) continue
try {
session.push(Pushes.anomaly, anomaly)
} catch {
// ignore
}
}
}
/**
* @param {object} payload
*/
export function broadcastHealth(payload) {
const list = peers.list()
if (!list.length) return
for (const session of list) {
if (session.closed) continue
try {
session.push(Pushes.health, payload)
} catch {
// ignore
}
}
}