revert: bot-side media pacing weg — pacing zit nu bridge-breed
De seriële send-keten + MEDIA_SEND_DELAY_MS in de bot teruggedraaid; de wwebjs-api bridge serialiseert + throttle de media-sends nu zelf (zie build-p25). Bot verstuurt weer direct. Docs/.env.example bijgewerkt.
This commit is contained in:
parent
2498380b41
commit
5d3683a8a0
5 changed files with 11 additions and 36 deletions
|
|
@ -25,7 +25,6 @@ MAX_REQUESTS_PER_DAY=5
|
||||||
ACK_STUCK_TIMEOUT_MS=300000 # 5 min zonder ack 2 = stuck
|
ACK_STUCK_TIMEOUT_MS=300000 # 5 min zonder ack 2 = stuck
|
||||||
ACK_PRUNED_AFTER_MS=1800000 # 30 min: stale trackings opruimen (loop stopt dan)
|
ACK_PRUNED_AFTER_MS=1800000 # 30 min: stale trackings opruimen (loop stopt dan)
|
||||||
ACK_CHECK_INTERVAL_MS=30000 # checkinterval (alleen actief als er iets pending is)
|
ACK_CHECK_INTERVAL_MS=30000 # checkinterval (alleen actief als er iets pending is)
|
||||||
MEDIA_SEND_DELAY_MS=500 # wacht ná élke media-send (media-pipeline is één tab; voorkomt overlappende sends)
|
|
||||||
|
|
||||||
# Admin notifications
|
# Admin notifications
|
||||||
ADMIN_NUMBER=31612345678@c.us
|
ADMIN_NUMBER=31612345678@c.us
|
||||||
|
|
|
||||||
12
AGENTS.md
12
AGENTS.md
|
|
@ -181,13 +181,11 @@ Sommige mediabestand-verzendingen keren `success` + message-ID terug maar worden
|
||||||
- **Pruning** na `ACK_PRUNED_AFTER_MS` (30 min); de check-loop is **activity-driven** (draait alleen bij openstaande tracking, geen polling in rust).
|
- **Pruning** na `ACK_PRUNED_AFTER_MS` (30 min); de check-loop is **activity-driven** (draait alleen bij openstaande tracking, geen polling in rust).
|
||||||
- Vereiste aan de bridge: `message_ack` staat sinds 2026-09-24 in wwebjs-api `.env` **niet** meer in `DISABLED_CALLBACKS`; container is daarvoor herstart.
|
- Vereiste aan de bridge: `message_ack` staat sinds 2026-09-24 in wwebjs-api `.env` **niet** meer in `DISABLED_CALLBACKS`; container is daarvoor herstart.
|
||||||
- Env-vars: `ACK_STUCK_TIMEOUT_MS` (default 300000), `ACK_PRUNED_AFTER_MS` (default 1800000), `ACK_CHECK_INTERVAL_MS` (default 30000).
|
- Env-vars: `ACK_STUCK_TIMEOUT_MS` (default 300000), `ACK_PRUNED_AFTER_MS` (default 1800000), `ACK_CHECK_INTERVAL_MS` (default 30000).
|
||||||
- **Media-spreiding:** `MEDIA_SEND_DELAY_MS` (default **500**; praktijktest op 500)
|
- **Media-pacing zit bridge-breed** (wwebjs-api, niet de bot): de bridge serialiseert
|
||||||
pauzeert **na élke media-send** (in `sendImageMessage`), niet alleen tussen pagina's van
|
media-sends en wacht `MEDIA_SEND_DELAY_MS` (bridge-.env) tussen twee sends — de
|
||||||
één dienst. De
|
wwebjs-media-pipeline is EEN chromium-tab; opeenvolgende media-sends (van wélke client
|
||||||
wwebjs-media-pipeline is EEN chromium-tab; opeenvolgende media-sends — óók naar
|
ook: dienst-bot, EBS, rss-forward) overlappen anders → staged-ghost-race. De bot zelf
|
||||||
verschillende ontvangers — overlappen anders en veroorzaken de staged-ghost-race.
|
pauzeert niet meer.
|
||||||
0 = uitschakelen. (Tijdelijke mitigatie; permanente fix = fork: send óf écht verzenden
|
|
||||||
óf zichtbaar falen, zie RCA.)
|
|
||||||
|
|
||||||
Logregels: `[ack] track <id> (<bestand> → <chat>)`, `[ack] delivered ack=<n> <id>`, `[ack] pruned <n> stale entries`.
|
Logregels: `[ack] track <id> (<bestand> → <chat>)`, `[ack] delivered ack=<n> <id>`, `[ack] pruned <n> stale entries`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,10 @@ sessie — zie AGENTS.md). De bot detecteert dit via `message_ack`-events en waa
|
||||||
| `ACK_STUCK_TIMEOUT_MS` | Leeftijd zonder ack 2 = stuck | `300000` (5 min) |
|
| `ACK_STUCK_TIMEOUT_MS` | Leeftijd zonder ack 2 = stuck | `300000` (5 min) |
|
||||||
| `ACK_PRUNED_AFTER_MS` | Stale tracking opruimen | `1800000` (30 min) |
|
| `ACK_PRUNED_AFTER_MS` | Stale tracking opruimen | `1800000` (30 min) |
|
||||||
| `ACK_CHECK_INTERVAL_MS` | Checkinterval (alleen actief bij pending) | `30000` |
|
| `ACK_CHECK_INTERVAL_MS` | Checkinterval (alleen actief bij pending) | `30000` |
|
||||||
| `MEDIA_SEND_DELAY_MS` | Wacht ná élke media-send (media-pipeline is één tab; voorkomt overlappende sends naar elk doel) | `500` |
|
|
||||||
|
> **Media-pacing:** zit bridge-breed (wwebjs-api), niet in de bot — zie AGENTS.md. De bot
|
||||||
|
> pauzeert niet tussen media-sends; de bridge serialiseert ze met `MEDIA_SEND_DELAY_MS`
|
||||||
|
> (bridge `.env`).
|
||||||
|
|
||||||
Opvallende logregels: `[ack] track …`, `[ack] delivered ack=…`, `[ack] pruned …`.
|
Opvallende logregels: `[ack] track …`, `[ack] delivered ack=…`, `[ack] pruned …`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ async function handleWebhook(payload) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pacing gebeurt nu centraal in sendImageMessage (na élke media-send), zodat óók
|
// Media-pacing voor opeenvolgende sends gebeurt bridge-breed (wwebjs-api
|
||||||
// afbeeldingen naar verschillende ontvangers niet overlappen in de ene chromium-tab.
|
// serialiseert + throttle de media-sends; MEDIA_SEND_DELAY_MS in bridge-.env).
|
||||||
const pngPaths = getPngFilePaths(dienst)
|
const pngPaths = getPngFilePaths(dienst)
|
||||||
if (!pngPaths || pngPaths.length === 0) {
|
if (!pngPaths || pngPaths.length === 0) {
|
||||||
await sendTextMessage(author, `Geen pagina's gevonden voor dienst ${dienstnummer}.`)
|
await sendTextMessage(author, `Geen pagina's gevonden voor dienst ${dienstnummer}.`)
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,6 @@ async function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms))
|
return new Promise(resolve => setTimeout(resolve, ms))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Media-send seriële keten: de wwebjs-media-pipeline is EÉN chromium-tab. Zonder
|
|
||||||
// serialisatie overlappen opeenvolgende media-sends — pagina's van één dienst óf
|
|
||||||
// afbeeldingen naar verschillende ontvangers bij gelijktijdige webhook-requests.
|
|
||||||
// Daarom loopt élke media-send door deze ene keten en eindigt elke send met
|
|
||||||
// MEDIA_SEND_DELAY_MS, zodat de tab tussen twee sends rust krijgt.
|
|
||||||
let mediaSendChain = Promise.resolve()
|
|
||||||
|
|
||||||
function enqueueSend(run) {
|
|
||||||
const job = mediaSendChain.then(run, run)
|
|
||||||
mediaSendChain = job.catch(() => {}) // keten levend houden, ook als een send faalt
|
|
||||||
return job
|
|
||||||
}
|
|
||||||
|
|
||||||
function isRetryableError(error) {
|
function isRetryableError(error) {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
const status = error.response.status
|
const status = error.response.status
|
||||||
|
|
@ -69,10 +56,6 @@ async function sendTextMessage(chatId, text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendImageMessage(chatId, filePath, filename) {
|
async function sendImageMessage(chatId, filePath, filename) {
|
||||||
return enqueueSend(() => sendImageMessageInner(chatId, filePath, filename))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendImageMessageInner(chatId, filePath, filename) {
|
|
||||||
return withRetry(async () => {
|
return withRetry(async () => {
|
||||||
const fileBuffer = fs.readFileSync(filePath)
|
const fileBuffer = fs.readFileSync(filePath)
|
||||||
const base64Data = fileBuffer.toString('base64')
|
const base64Data = fileBuffer.toString('base64')
|
||||||
|
|
@ -88,14 +71,6 @@ async function sendImageMessageInner(chatId, filePath, filename) {
|
||||||
})
|
})
|
||||||
const messageId = response.data?.message?._data?.id?.id
|
const messageId = response.data?.message?._data?.id?.id
|
||||||
registerSend(messageId, chatId, filename)
|
registerSend(messageId, chatId, filename)
|
||||||
// Pacing ná élke media-send: de wwebjs-media-pipeline is EEN chromium-tab. Twee
|
|
||||||
// opeenvolgende media-sends (pagina's van één dienst óf afbeeldingen naar
|
|
||||||
// verschillende ontvangers) mogen niet overlappen — dat veroorzaakt de staged-
|
|
||||||
// ghost-race (2e send verliest). Wacht dus altijd MEDIA_SEND_DELAY_MS ná een send.
|
|
||||||
const mediaSendDelayMs = parseInt(process.env.MEDIA_SEND_DELAY_MS, 10) || 500
|
|
||||||
if (mediaSendDelayMs > 0) {
|
|
||||||
await sleep(mediaSendDelayMs)
|
|
||||||
}
|
|
||||||
return response.data
|
return response.data
|
||||||
}, `sendImageMessage ${filename} to ${chatId}`)
|
}, `sendImageMessage ${filename} to ${chatId}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue