mirror of
https://github.com/hansjone/netxops.git
synced 2026-10-09 05:10:45 +08:00
Fix key-alarm IM delivery blocked by DSH session sink.
Run session and WhatsApp/IM sinks in parallel so a failing or slow sticky session no longer skips proactive IM delivery (0.1.34). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
3a731389f0
commit
da08c38949
5 changed files with 157 additions and 15 deletions
16
src/index.ts
16
src/index.ts
|
|
@ -35,8 +35,8 @@ import {
|
|||
publishAlarmPushStatus,
|
||||
resetAlarmPushStatus,
|
||||
} from './netx/alarm-push-status.ts'
|
||||
import { deliverAlarmToIm } from './netx/alarm-im.ts'
|
||||
import { deliverAlarmToSession, resetAlarmSession } from './netx/alarm-session.ts'
|
||||
import { dispatchAlarmToSinks } from './netx/alarm-dispatch.ts'
|
||||
import { resetAlarmSession } from './netx/alarm-session.ts'
|
||||
import {
|
||||
capabilityGroupsFromSettings,
|
||||
groupsForPlane,
|
||||
|
|
@ -307,18 +307,18 @@ export function apply(ctx: Context, config: Config = Config({})): void {
|
|||
imBotId: current.imBotId ?? '',
|
||||
imTargetId: current.imTargetId ?? '',
|
||||
})
|
||||
// Prefer target list presence; UI also mirrors this into alarmDeliverIm.
|
||||
const deliverIm = imTargets.length > 0
|
||||
stopAlarmPush = startAlarmPushClient({
|
||||
apiUrl,
|
||||
token,
|
||||
logger: ctx.logger,
|
||||
onAlarm: async (payload) => {
|
||||
if (deliverDsh) {
|
||||
await deliverAlarmToSession(ctx, payload, lang)
|
||||
}
|
||||
await deliverAlarmToIm(ctx, payload, {
|
||||
enabled: deliverIm,
|
||||
targets: imTargets,
|
||||
// Parallel sinks: a stuck/failing DSH sticky session must not block WhatsApp/IM.
|
||||
await dispatchAlarmToSinks(ctx, payload, {
|
||||
deliverDsh,
|
||||
deliverIm,
|
||||
imTargets,
|
||||
lang,
|
||||
})
|
||||
},
|
||||
|
|
|
|||
54
src/netx/alarm-dispatch.ts
Normal file
54
src/netx/alarm-dispatch.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Fan-out one key-alarm to optional DSH session + IM sinks.
|
||||
* Sinks run in parallel so a failing/slow session path cannot block WhatsApp/IM.
|
||||
*/
|
||||
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import { deliverAlarmToIm, type AlarmImDeliveryOptions } from './alarm-im.ts'
|
||||
import { deliverAlarmToSession } from './alarm-session.ts'
|
||||
import type { KeyAlarmPayload } from './alarm-push.ts'
|
||||
import type { ImDeliveryTarget } from './im-targets.ts'
|
||||
|
||||
export interface AlarmSinkDispatchOptions {
|
||||
deliverDsh: boolean
|
||||
deliverIm: boolean
|
||||
imTargets: readonly ImDeliveryTarget[]
|
||||
lang: string
|
||||
}
|
||||
|
||||
export interface AlarmSinkFns {
|
||||
toSession?: typeof deliverAlarmToSession
|
||||
toIm?: typeof deliverAlarmToIm
|
||||
}
|
||||
|
||||
/**
|
||||
* Deliver to every enabled sink; never let one sink's rejection cancel the others.
|
||||
* @returns settled results in order: [session?, im] (session omitted when deliverDsh is false).
|
||||
*/
|
||||
export async function dispatchAlarmToSinks(
|
||||
ctx: Context,
|
||||
payload: KeyAlarmPayload,
|
||||
options: AlarmSinkDispatchOptions,
|
||||
sinks: AlarmSinkFns = {},
|
||||
): Promise<PromiseSettledResult<void>[]> {
|
||||
const toSession = sinks.toSession ?? deliverAlarmToSession
|
||||
const toIm = sinks.toIm ?? deliverAlarmToIm
|
||||
const jobs: Array<Promise<void>> = []
|
||||
if (options.deliverDsh) {
|
||||
jobs.push(toSession(ctx, payload, options.lang))
|
||||
}
|
||||
const imOptions: AlarmImDeliveryOptions = {
|
||||
enabled: options.deliverIm,
|
||||
targets: options.imTargets,
|
||||
lang: options.lang,
|
||||
}
|
||||
jobs.push(toIm(ctx, payload, imOptions))
|
||||
|
||||
const results = await Promise.allSettled(jobs)
|
||||
for (const result of results) {
|
||||
if (result.status === 'rejected') {
|
||||
ctx.logger.warn('netxops alarm-push: sink failed: %s', result.reason)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue