Skip to content

Commit 4495e1c

Browse files
committed
chore: toobusy & env & logs
1 parent 81f6f97 commit 4495e1c

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"redis": "^4.6.12",
6666
"socket.io": "^4.7.5",
6767
"socket.io-client": "^4.8.0",
68+
"toobusy-js": "^0.5.1",
6869
"y-protocols": "^1.0.6",
6970
"yjs": "^13.6.18"
7071
},
@@ -80,6 +81,7 @@
8081
"@dotenvx/dotenvx": "^1.14.0",
8182
"@redis/client": "^1.6.0",
8283
"@types/node": "^20.11.5",
84+
"@types/toobusy-js": "^0.5.4",
8385
"@types/ws": "^8.5.10",
8486
"concurrently": "^8.2.2",
8587
"standard": "^17.1.0",

pnpm-lock.yaml

+17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/y-socket-io/y-socket-io.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,23 @@ import * as decoding from 'lib0/decoding'
66
import { assert } from 'lib0/testing'
77
import * as api from '../api.js'
88
import * as protocol from '../protocol.js'
9+
import * as number from 'lib0/number'
10+
import * as env from 'lib0/environment'
911
import { createSubscriber } from '../subscriber.js'
1012
import { isDeepStrictEqual } from 'util'
1113
import { User } from './user.js'
14+
import { createModuleLogger } from 'lib0/logging'
15+
import toobusy from 'toobusy-js'
1216

13-
const PERSIST_INTERVAL = 5000
17+
const logSocketIO = createModuleLogger('@y/socket-io/server')
18+
const PERSIST_INTERVAL = number.parseInt(env.getConf('y-socket-io-server-persist-interval') || '3000')
19+
const REVALIDATE_TIMEOUT = number.parseInt(env.getConf('y-socket-io-server-revalidate-timeout') || '60000')
20+
21+
process.on('SIGINT', function() {
22+
// calling .shutdown allows your process to exit normally
23+
toobusy.shutdown();
24+
process.exit();
25+
});
1426

1527
/**
1628
* @typedef {import('socket.io').Namespace} Namespace
@@ -141,7 +153,7 @@ export class YSocketIO {
141153
if (this.configuration.authenticate === null) return next()
142154
const userCache = this.socketUserCache.get(socket)
143155
const namespace = this.getNamespaceString(socket.nsp)
144-
if (!userCache || Date.now() - userCache.validatedAt > 60_000) {
156+
if (!userCache || Date.now() - userCache.validatedAt > REVALIDATE_TIMEOUT) {
145157
this.socketUserCache.delete(socket)
146158
const user = await this.configuration.authenticate(socket)
147159
if (!user) return next(new Error('Unauthorized'))
@@ -158,9 +170,14 @@ export class YSocketIO {
158170
this.nsp.on('connection', async (socket) => {
159171
assert(this.client)
160172
assert(this.subscriber)
173+
const namespace = this.getNamespaceString(socket.nsp)
174+
if (toobusy()) {
175+
logSocketIO(`warning server too busy, rejecting connection: ${namespace}`)
176+
throw new Error('server too busy, please try again latter')
177+
}
161178
if (!socket.user) throw new Error('user does not exist in socket')
162179

163-
const namespace = this.getNamespaceString(socket.nsp)
180+
logSocketIO(`new connection in namespace: ${namespace}`)
164181
const stream = api.computeRedisRoomStreamName(
165182
namespace,
166183
'index',
@@ -409,7 +426,7 @@ export class YSocketIO {
409426
changed = getDoc.changed
410427
}
411428
assert(doc)
412-
if (changed) this.debouncedPersist(namespace, doc.ydoc)
429+
this.debouncedPersist(namespace, doc.ydoc)
413430
this.namespaceDocMap.get(namespace)?.ydoc.destroy()
414431
this.namespaceDocMap.set(namespace, doc)
415432
await this.client.trimRoomStream(namespace, 'index', nsp.sockets.size === 0)

0 commit comments

Comments
 (0)