我們使用以下代碼將查詢結果流式傳輸回客戶端:
app.get('/events', (req, res) => {
try {
const stream = db('events')
.select('*')
.where({ id_session: req.query.id_session })
.stream()
stream.pipe(JSONStream.stringify()).pipe(res)
} catch (err) {
next(err)
}
})
雖然代碼似乎具有出色的記憶體使用情況(穩定/低記憶體使用),但它會創建隨機池獲取超時:
Knex:獲取連接超時。游泳池可能已經滿了。您是否錯過了 .transacting(trx) 電話?
這在生產中以看似隨機的間隔發生。知道為什么嗎?
uj5u.com熱心網友回復:
發生這種情況是因為中止的請求(即客戶端在請求中關閉瀏覽器)不會將連接釋放回池中。
首先,確保您使用的是最新的膝關節;或至少v0.21.3 已經引入了對流/池處理的修復。
從那時起,您有幾個選擇:
使用pipeline而不是pipewhich 正確處理中止的請求,如下所示:
const { pipeline } = require('stream')
app.get('/events', (req, res) => {
try {
const stream = db('events')
.select('*')
.where({ id_session: req.query.id_session })
.stream()
return pipeline(stream, JSONStream.stringify(), res, err => {
if (err) {
return console.log(`Pipeline failed with err:`, err)
}
console.log(`Pipeline ended succesfully`)
})
} catch (err) {
next(err)
}
})
或監聽close事件req并自己銷毀資料庫流,如下所示:
app.get('/events', (req, res) => {
try {
const stream = db('events')
.select('*')
.where({ id_session: req.query.id_session })
.stream()
// Not listening to this event will crash the process if
// stream.destroy(err) is called.
stream.on('error', () => {
console.log('Stream was destroyed')
})
req.on('close', () => {
// stream.end() does not seem to work, only destroy()
stream.destroy('Aborted request')
})
stream.pipe(JSONStream.stringify()).pipe(res)
} catch (err) {
next(err)
}
})
有用的閱讀:
- knex Wiki:手動關閉流。小心,
stream.end這里提到的似乎不起作用。 - knex 問題:stream.end() 不回傳與池的連接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/333168.html
標籤:PostgreSQL 表达 溪流 膝关节
