fix: memory leak on connections
Massimo Melina committed
Aug 1, 2022 at 00:37 UTC
8b48dff808b8d9042f278431760ded7de3850c50
2 files changed
+10
-4
server/src/throttler.ts
+8
-4
@@ -5,7 +5,7 @@ import Koa from 'koa'
5
import { ThrottledStream, ThrottleGroup } from './ThrottledStream'
6
import { defineConfig } from './config'
7
import { getOrSet, isLocalHost } from './misc'
8
-import { updateConnection } from './connections'
8
+import { Connection, updateConnection } from './connections'
9
import _ from 'lodash'
10
11
const mainThrottleGroup = new ThrottleGroup(Infinity)
@@ -38,19 +38,22 @@ export const throttler: Koa.Middleware = async (ctx, next) => {
38
group.updateLimit(v))
39
return { group, count:0, destroy: unsub }
40
})
41
- const conn = ctx.state.connection
41
+ const conn = ctx.state.connection as Connection | undefined
42
if (!conn) throw 'assert throttler connection'
43
44
const ts = conn[SymThrStr] = new ThrottledStream(ipGroup.group, conn[SymThrStr])
45
+ let closed = false
46
47
const DELAY = 1000
48
const update = _.debounce(() => {
48
- const ts = conn[SymThrStr]
49
+ const ts = conn[SymThrStr] as ThrottledStream
50
const speed = ts.getSpeed()
51
const outSpeed = _.round(speed, 1) || _.round(speed, 3) // further precision if necessary
52
updateConnection(conn, { outSpeed, sent: ts.getBytesSent() })
53
+ /* in case this stream stands still for a while (before the end), we'll have neither 'sent' or 'close' events,
54
+ * so who will take care to updateConnection? This artificial next-call will ensure just that */
55
clearTimeout(conn[SymTimeout])
53
- if (outSpeed || !(ts.finished || ts.ended))
56
+ if (outSpeed || !closed)
57
conn[SymTimeout] = setTimeout(update, DELAY)
58
}, DELAY, { maxWait:DELAY })
59
ts.on('sent', update)
@@ -58,6 +61,7 @@ export const throttler: Koa.Middleware = async (ctx, next) => {
61
++ipGroup.count
62
ts.on('close', ()=> {
63
update.flush()
64
+ closed = true
65
if (--ipGroup.count) return // any left?
66
ipGroup.destroy?.()
67
delete ip2group[ctx.ip]
todo.md
+2
@@ -1,6 +1,8 @@
1
# To do
2
+- fix: currently user field in the access.log is '-'
3
- admin: check + update
4
- admin/monitor: account column
5
+- admin/monitor: show total throughput
6
- frontend: hide closer button on login dialog accessing a protected resource, as it's no use
7
- easier nat life
8
- show public ip use, https://github.com/sindresorhus/public-ip