Fix SessionStore concurrency in tests by debouncing fn
This commit is contained in:
parent
803bbfa0fe
commit
2256fbc1e8
@ -13,6 +13,5 @@ module.exports = {
|
||||
'jsx'
|
||||
],
|
||||
setupFiles: ['<rootDir>/jest.setup.js'],
|
||||
maxConcurrency: 1,
|
||||
verbose: false
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {Store} from 'express-session'
|
||||
import {ISession} from './ISession'
|
||||
import {Repository, LessThan} from 'typeorm'
|
||||
import {debounce} from '@rondo.dev/tasq'
|
||||
|
||||
type SessionData = Express.SessionData
|
||||
type Callback = (err?: any, session?: SessionData) => void
|
||||
@ -23,12 +24,25 @@ export type TRepositoryFactory<T> = () => Repository<T>
|
||||
export class SessionStore<S extends ISession> extends Store {
|
||||
|
||||
protected readonly getRepository: TRepositoryFactory<S>
|
||||
protected readonly cleanup: (...args: never[]) => void
|
||||
|
||||
constructor(
|
||||
protected readonly options: ISessionStoreOptions<S>,
|
||||
) {
|
||||
super()
|
||||
this.getRepository = options.getRepository
|
||||
|
||||
this.cleanup = debounce(async () => {
|
||||
try {
|
||||
const now = Date.now()
|
||||
// FIXME causes deadlocks in tests
|
||||
await this.getRepository().delete({
|
||||
expiredAt: LessThan(now),
|
||||
} as any)
|
||||
} catch (err) {
|
||||
console.log('error cleaning sessions', err)
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
protected async promiseToCallback<T>(
|
||||
@ -61,16 +75,17 @@ export class SessionStore<S extends ISession> extends Store {
|
||||
}
|
||||
|
||||
set = (sid: string, session: SessionData, callback?: CallbackErr) => {
|
||||
const promise1 = this.options.cleanup
|
||||
? this.cleanup() : Promise.resolve()
|
||||
const promise2 = promise1.then(() => this.saveSession(
|
||||
const promise = Promise.resolve()
|
||||
.then(() => this.saveSession(
|
||||
this.options.buildSession(session, {
|
||||
id: sid,
|
||||
expiredAt: Date.now() + this.getTTL(session) * 1000,
|
||||
json: JSON.stringify(session),
|
||||
}),
|
||||
))
|
||||
this.promiseToCallback(promise2, callback)
|
||||
this.promiseToCallback(promise, callback)
|
||||
|
||||
this.cleanup()
|
||||
}
|
||||
|
||||
destroy = (sid: string, callback?: CallbackErr) => {
|
||||
@ -99,12 +114,4 @@ export class SessionStore<S extends ISession> extends Store {
|
||||
return typeof maxAge === 'number' ? maxAge : this.options.ttl
|
||||
}
|
||||
|
||||
protected async cleanup() {
|
||||
const now = Date.now()
|
||||
// FIXME causes deadlocks in tests
|
||||
await this.getRepository().delete({
|
||||
expiredAt: LessThan(now),
|
||||
} as any)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
{"path": "../common"},
|
||||
{"path": "../jsonrpc"},
|
||||
{"path": "../logger"},
|
||||
{"path": "../config"}
|
||||
{"path": "../config"},
|
||||
{"path": "../tasq"}
|
||||
]
|
||||
}
|
||||
|
||||
@ -10,5 +10,6 @@
|
||||
"dependencies": {},
|
||||
"types": "lib/index.d.ts",
|
||||
"devDependencies": {},
|
||||
"module": "lib/index.js"
|
||||
"module": "lib/index.js",
|
||||
"main": "lib/index.js"
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
export function debounce<A, R>(fn: (...args: A[]) => R, delay: number) {
|
||||
let timeout: NodeJS.Timeout | null = null
|
||||
|
||||
return async function debounceImpl(...args: A[]) {
|
||||
return function debounceImpl(...args: A[]): void {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user