Skip to content

Commit 0b51b65

Browse files
authored
Merge pull request #26 from hackmdio/fix/use-ttl-to-delete-inactive-room
fix/avoid race condition by preserving room until no connection
2 parents ec69cf4 + ac1f004 commit 0b51b65

File tree

2 files changed

+9
-22
lines changed

2 files changed

+9
-22
lines changed

src/api.js

+8-11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ if (ydocUpdateCallback != null && ydocUpdateCallback.slice(-1) !== '/') {
2020
ydocUpdateCallback += '/'
2121
}
2222
const WORKER_DISABLED = env.getConf('y-worker-disabled') === 'true'
23+
const ROOM_STREAM_TTL = number.parseInt(env.getConf('y-room-stream-ttl') || '300')
2324

2425
/**
2526
* @param {string} a
@@ -125,14 +126,18 @@ export class Api {
125126
this.persistWorker = null
126127

127128
const addScript = WORKER_DISABLED
128-
? 'redis.call("XADD", KEYS[1], "*", "m", ARGV[1])'
129+
? `
130+
redis.call("XADD", KEYS[1], "*", "m", ARGV[1])
131+
redis.call("EXPIRE", KEYS[1], ${ROOM_STREAM_TTL})
132+
`
129133
: `
130134
if redis.call("EXISTS", KEYS[1]) == 0 then
131135
redis.call("XADD", "${this.redisWorkerStreamName}", "*", "compact", KEYS[1])
132136
elseif redis.call("XLEN", KEYS[1]) > 100 then
133137
redis.call("SADD", "${this.prefix}:worker:checklist", KEYS[1])
134138
end
135139
redis.call("XADD", KEYS[1], "*", "m", ARGV[1])
140+
redis.call("EXPIRE", KEYS[1], ${ROOM_STREAM_TTL})
136141
`
137142

138143
this.redis = redis.createClient({
@@ -294,20 +299,12 @@ export class Api {
294299
/**
295300
* @param {string} room
296301
* @param {string} docid
297-
* @param {boolean} [remove=false]
298302
*/
299-
async trimRoomStream (room, docid, remove = false) {
303+
async trimRoomStream (room, docid) {
300304
const roomName = computeRedisRoomStreamName(room, docid, this.prefix)
301305
const redisLastId = await this.getRedisLastId(room, docid)
302306
const lastId = number.parseInt(redisLastId.split('-')[0])
303-
if (remove) {
304-
await this.redis.del(roomName)
305-
} else {
306-
await this.redis.multi()
307-
.xTrim(roomName, 'MINID', lastId - this.redisMinMessageLifetime)
308-
.xDelIfEmpty(roomName)
309-
.exec()
310-
}
307+
await this.redis.xTrim(roomName, 'MINID', lastId - this.redisMinMessageLifetime)
311308
}
312309

313310
/**

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

+1-11
Original file line numberDiff line numberDiff line change
@@ -537,16 +537,7 @@ export class YSocketIO {
537537
await this.client.store.persistDoc(namespace, 'index', doc)
538538
}
539539

540-
/**
541-
* there's a possibility where the namespace is deleted after the
542-
* persist promise resolved, so we have to check if the room still
543-
* exist.
544-
* @see cleanupNamespace
545-
* @see cleanupNamespaceImpl
546-
*/
547-
if (this.namespaceMap.has(namespace)) {
548-
await this.client.trimRoomStream(namespace, 'index')
549-
}
540+
await this.client.trimRoomStream(namespace, 'index')
550541
} catch (e) {
551542
console.error(e)
552543
} finally {
@@ -687,6 +678,5 @@ export class YSocketIO {
687678
this.namespaceDocMap.get(namespace)?.ydoc.destroy()
688679
this.namespaceDocMap.delete(namespace)
689680
this.namespacePersistentMap.delete(namespace)
690-
this.client?.trimRoomStream(namespace, 'index', true)
691681
}
692682
}

0 commit comments

Comments
 (0)