From 064599c942011b2827ae497f9d03974494537d22 Mon Sep 17 00:00:00 2001 From: Martin Lehmann Date: Thu, 11 Nov 2021 20:29:40 +0100 Subject: [PATCH] fix: refactor client-metrics list and ttl-list to TypeScript (#1080) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ivar Conradi Ă˜sthus --- src/lib/services/client-metrics/index.ts | 7 +-- .../{list.test.js => list.test.ts} | 6 +-- .../client-metrics/{list.js => list.ts} | 34 +++++++++----- .../{ttl-list.test.js => ttl-list.test.ts} | 12 +++-- .../{ttl-list.js => ttl-list.ts} | 45 +++++++++++++------ 5 files changed, 64 insertions(+), 40 deletions(-) rename src/lib/services/client-metrics/{list.test.js => list.test.ts} (97%) rename src/lib/services/client-metrics/{list.js => list.ts} (82%) rename src/lib/services/client-metrics/{ttl-list.test.js => ttl-list.test.ts} (90%) rename src/lib/services/client-metrics/{ttl-list.js => ttl-list.ts} (66%) diff --git a/src/lib/services/client-metrics/index.ts b/src/lib/services/client-metrics/index.ts index 874261eff4..1b7fd49498 100644 --- a/src/lib/services/client-metrics/index.ts +++ b/src/lib/services/client-metrics/index.ts @@ -22,12 +22,13 @@ import { IMetricsBucket, } from '../../types/model'; import { clientRegisterSchema } from './register-schema'; + import { minutesToMilliseconds, parseISO, secondsToMilliseconds, } from 'date-fns'; -import TTLList = require('./ttl-list'); +import TTLList from './ttl-list'; export default class ClientMetricsService { globalCount = 0; @@ -38,13 +39,13 @@ export default class ClientMetricsService { lastMinuteProjection = new Projection(); - lastHourList = new TTLList({ + lastHourList = new TTLList({ interval: secondsToMilliseconds(10), }); logger = null; - lastMinuteList = new TTLList({ + lastMinuteList = new TTLList({ interval: secondsToMilliseconds(10), expireType: 'minutes', expireAmount: 1, diff --git a/src/lib/services/client-metrics/list.test.js b/src/lib/services/client-metrics/list.test.ts similarity index 97% rename from src/lib/services/client-metrics/list.test.js rename to src/lib/services/client-metrics/list.test.ts index 73a30e45fa..1eb1c0fdf5 100644 --- a/src/lib/services/client-metrics/list.test.js +++ b/src/lib/services/client-metrics/list.test.ts @@ -1,9 +1,7 @@ -'use strict'; - -const List = require('./list'); +import List from './list'; function getList() { - const list = new List(); + const list = new List(); list.add(1); list.add(2); list.add(3); diff --git a/src/lib/services/client-metrics/list.js b/src/lib/services/client-metrics/list.ts similarity index 82% rename from src/lib/services/client-metrics/list.js rename to src/lib/services/client-metrics/list.ts index e0829352de..8a1d55eccf 100644 --- a/src/lib/services/client-metrics/list.js +++ b/src/lib/services/client-metrics/list.ts @@ -1,31 +1,41 @@ /* eslint-disable no-param-reassign */ /* eslint-disable max-classes-per-file */ -'use strict'; +import { EventEmitter } from 'events'; -const { EventEmitter } = require('events'); +class Node { + value: T | null; -class Node { - constructor(value) { + prev: Node | null; + + next: Node | null; + + constructor(value: T) { this.value = value; this.next = null; } - link(next) { + link(next: Node) { this.next = next; next.prev = this; return this; } } -module.exports = class List extends EventEmitter { +type IteratorFn = (cursor: Node) => U; + +export default class List extends EventEmitter { + private start: Node | null; + + private tail: Node | null; + constructor() { super(); this.start = null; this.tail = null; } - add(obj) { + add(obj: T): Node { const node = new Node(obj); if (this.start) { this.start = node.link(this.start); @@ -36,7 +46,7 @@ module.exports = class List extends EventEmitter { return node; } - iterate(fn) { + iterate(fn: IteratorFn): void { if (!this.start) { return; } @@ -51,7 +61,7 @@ module.exports = class List extends EventEmitter { } } - iterateReverse(fn) { + iterateReverse(fn: IteratorFn): void { if (!this.tail) { return; } @@ -66,7 +76,7 @@ module.exports = class List extends EventEmitter { } } - reverseRemoveUntilTrue(fn) { + reverseRemoveUntilTrue(fn: IteratorFn): void { if (!this.tail) { return; } @@ -98,7 +108,7 @@ module.exports = class List extends EventEmitter { } } - toArray() { + toArray(): T[] { const result = []; if (this.start) { @@ -125,4 +135,4 @@ module.exports = class List extends EventEmitter { // return result; // } -}; +} diff --git a/src/lib/services/client-metrics/ttl-list.test.js b/src/lib/services/client-metrics/ttl-list.test.ts similarity index 90% rename from src/lib/services/client-metrics/ttl-list.test.js rename to src/lib/services/client-metrics/ttl-list.test.ts index fc4d39d20b..e2349b2804 100644 --- a/src/lib/services/client-metrics/ttl-list.test.js +++ b/src/lib/services/client-metrics/ttl-list.test.ts @@ -1,11 +1,9 @@ -'use strict'; - -const TTLList = require('./ttl-list'); -const { addMilliseconds } = require('date-fns'); +import { addMilliseconds } from 'date-fns'; +import TTLList from './ttl-list'; test('should emit expire', (done) => { jest.useFakeTimers('modern'); - const list = new TTLList({ + const list = new TTLList<{ n: number }>({ interval: 20, expireAmount: 10, expireType: 'milliseconds', @@ -25,7 +23,7 @@ test('should emit expire', (done) => { test('should slice off list', () => { jest.useFakeTimers('modern'); - const list = new TTLList({ + const list = new TTLList<{ n: string }>({ interval: 10, expireAmount: 10, expireType: 'milliseconds', @@ -69,7 +67,7 @@ test('should slice off list', () => { test('should add item created in the past but expiring in the future', () => { jest.useFakeTimers('modern'); - const list = new TTLList({ + const list = new TTLList<{ n: string }>({ interval: 10, expireAmount: 10, expireType: 'milliseconds', diff --git a/src/lib/services/client-metrics/ttl-list.js b/src/lib/services/client-metrics/ttl-list.ts similarity index 66% rename from src/lib/services/client-metrics/ttl-list.js rename to src/lib/services/client-metrics/ttl-list.ts index e81538cb30..a09bffe9f2 100644 --- a/src/lib/services/client-metrics/ttl-list.js +++ b/src/lib/services/client-metrics/ttl-list.ts @@ -1,21 +1,38 @@ -'use strict'; - -const { EventEmitter } = require('events'); -const List = require('./list'); -const { +import { EventEmitter } from 'events'; +import List from './list'; +import { add, - isFuture, addMilliseconds, secondsToMilliseconds, -} = require('date-fns'); + Duration, + isFuture, +} from 'date-fns'; + +interface ConstructorArgs { + interval: number; + expireAmount: number; + expireType: keyof Duration | 'milliseconds'; +} // this list must have entries with sorted ttl range -module.exports = class TTLList extends EventEmitter { +export default class TTLList extends EventEmitter { + private readonly interval: number; + + private readonly expireAmount: number; + + private readonly expireType: keyof Duration | 'milliseconds'; + + public list: List<{ ttl: Date; value: T }>; + + private timer: NodeJS.Timeout; + + private readonly getExpiryFrom: (timestamp) => Date; + constructor({ interval = secondsToMilliseconds(1), expireAmount = 1, expireType = 'hours', - } = {}) { + }: Partial = {}) { super(); this.interval = interval; this.expireAmount = expireAmount; @@ -37,7 +54,7 @@ module.exports = class TTLList extends EventEmitter { this.startTimer(); } - startTimer() { + startTimer(): void { if (this.list) { this.timer = setTimeout(() => { if (this.list) { @@ -48,7 +65,7 @@ module.exports = class TTLList extends EventEmitter { } } - add(value, timestamp = new Date()) { + add(value: T, timestamp = new Date()): void { const ttl = this.getExpiryFrom(timestamp); if (isFuture(ttl)) { this.list.add({ ttl, value }); @@ -57,14 +74,14 @@ module.exports = class TTLList extends EventEmitter { } } - timedCheck() { + timedCheck(): void { this.list.reverseRemoveUntilTrue(({ value }) => isFuture(value.ttl)); this.startTimer(); } - destroy() { + destroy(): void { clearTimeout(this.timer); this.timer = null; this.list = null; } -}; +}