From 2256fbc1e8262f377b25af62abe66a848bb918d5 Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Mon, 26 Aug 2019 20:13:35 +0700 Subject: [PATCH] Fix SessionStore concurrency in tests by debouncing fn --- packages/server/jest.config.js | 1 - packages/server/src/session/SessionStore.ts | 31 +++++++++++++-------- packages/server/tsconfig.json | 3 +- packages/tasq/package.json | 3 +- packages/tasq/src/debounce.ts | 2 +- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/server/jest.config.js b/packages/server/jest.config.js index 3a4457a..7b62f2d 100644 --- a/packages/server/jest.config.js +++ b/packages/server/jest.config.js @@ -13,6 +13,5 @@ module.exports = { 'jsx' ], setupFiles: ['/jest.setup.js'], - maxConcurrency: 1, verbose: false } diff --git a/packages/server/src/session/SessionStore.ts b/packages/server/src/session/SessionStore.ts index cd43007..1fafdbb 100644 --- a/packages/server/src/session/SessionStore.ts +++ b/packages/server/src/session/SessionStore.ts @@ -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 = () => Repository export class SessionStore extends Store { protected readonly getRepository: TRepositoryFactory + protected readonly cleanup: (...args: never[]) => void constructor( protected readonly options: ISessionStoreOptions, ) { 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( @@ -61,16 +75,17 @@ export class SessionStore 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 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) - } - } diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 682d90f..a1e148c 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -8,6 +8,7 @@ {"path": "../common"}, {"path": "../jsonrpc"}, {"path": "../logger"}, - {"path": "../config"} + {"path": "../config"}, + {"path": "../tasq"} ] } diff --git a/packages/tasq/package.json b/packages/tasq/package.json index 1473313..b2b25eb 100644 --- a/packages/tasq/package.json +++ b/packages/tasq/package.json @@ -10,5 +10,6 @@ "dependencies": {}, "types": "lib/index.d.ts", "devDependencies": {}, - "module": "lib/index.js" + "module": "lib/index.js", + "main": "lib/index.js" } diff --git a/packages/tasq/src/debounce.ts b/packages/tasq/src/debounce.ts index e7418dc..b50e2f9 100644 --- a/packages/tasq/src/debounce.ts +++ b/packages/tasq/src/debounce.ts @@ -1,7 +1,7 @@ export function debounce(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) }