diff options
author | kontrollanten <6680299+kontrollanten@users.noreply.github.com> | 2022-11-14 18:26:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-14 16:26:20 +0100 |
commit | 564b9b55976873d87e669ace916f037b72fe2865 (patch) | |
tree | 8c3c097cf3a34766e60fa1bdcf1de7d8558eff8c | |
parent | ff91b644fb1b063d0a8eff7492beb1a9bf7e4ce1 (diff) | |
download | PeerTube-564b9b55976873d87e669ace916f037b72fe2865.tar.gz PeerTube-564b9b55976873d87e669ace916f037b72fe2865.tar.zst PeerTube-564b9b55976873d87e669ace916f037b72fe2865.zip |
refactor(server): redis > ioredis (#5371)
* refactor(server): redis > ioredis
* refactor(JobQueue): reuse redis connection builder
* fix(redisio)
* fix(redis): setValue
* feat(redis): showFriendlyErrorStack
* feat(redis): auto pipelining
https://github.com/luin/ioredis/blob/308017a6b9429c16b074e03e70f5524499476fa9/README.md#autopipelining
* dont use autopipelining for bullmq
* ioredis events
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | server/lib/job-queue/job-queue.ts | 21 | ||||
-rw-r--r-- | server/lib/redis.ts | 82 | ||||
-rw-r--r-- | server/middlewares/cache/shared/api-cache.ts | 6 | ||||
-rw-r--r-- | yarn.lock | 65 |
5 files changed, 57 insertions, 119 deletions
diff --git a/package.json b/package.json index 249455068..f0115fdbc 100644 --- a/package.json +++ b/package.json | |||
@@ -129,6 +129,7 @@ | |||
129 | "helmet": "^6.0.0", | 129 | "helmet": "^6.0.0", |
130 | "hpagent": "^1.0.0", | 130 | "hpagent": "^1.0.0", |
131 | "http-problem-details": "^0.1.5", | 131 | "http-problem-details": "^0.1.5", |
132 | "ioredis": "^5.2.3", | ||
132 | "ip-anonymize": "^0.1.0", | 133 | "ip-anonymize": "^0.1.0", |
133 | "ipaddr.js": "2.0.1", | 134 | "ipaddr.js": "2.0.1", |
134 | "is-cidr": "^4.0.0", | 135 | "is-cidr": "^4.0.0", |
@@ -157,7 +158,6 @@ | |||
157 | "prompt": "^1.0.0", | 158 | "prompt": "^1.0.0", |
158 | "proxy-addr": "^2.0.7", | 159 | "proxy-addr": "^2.0.7", |
159 | "pug": "^3.0.0", | 160 | "pug": "^3.0.0", |
160 | "redis": "^4.0.1", | ||
161 | "reflect-metadata": "^0.1.12", | 161 | "reflect-metadata": "^0.1.12", |
162 | "sanitize-html": "2.x", | 162 | "sanitize-html": "2.x", |
163 | "sequelize": "6.21.6", | 163 | "sequelize": "6.21.6", |
diff --git a/server/lib/job-queue/job-queue.ts b/server/lib/job-queue/job-queue.ts index 655be6568..6bc59732f 100644 --- a/server/lib/job-queue/job-queue.ts +++ b/server/lib/job-queue/job-queue.ts | |||
@@ -63,6 +63,7 @@ import { processVideoLiveEnding } from './handlers/video-live-ending' | |||
63 | import { processVideoStudioEdition } from './handlers/video-studio-edition' | 63 | import { processVideoStudioEdition } from './handlers/video-studio-edition' |
64 | import { processVideoTranscoding } from './handlers/video-transcoding' | 64 | import { processVideoTranscoding } from './handlers/video-transcoding' |
65 | import { processVideosViewsStats } from './handlers/video-views-stats' | 65 | import { processVideosViewsStats } from './handlers/video-views-stats' |
66 | import { Redis } from '../redis' | ||
66 | 67 | ||
67 | export type CreateJobArgument = | 68 | export type CreateJobArgument = |
68 | { type: 'activitypub-http-broadcast', payload: ActivitypubHttpBroadcastPayload } | | 69 | { type: 'activitypub-http-broadcast', payload: ActivitypubHttpBroadcastPayload } | |
@@ -183,7 +184,7 @@ class JobQueue { | |||
183 | } | 184 | } |
184 | 185 | ||
185 | this.flowProducer = new FlowProducer({ | 186 | this.flowProducer = new FlowProducer({ |
186 | connection: this.getRedisConnection(), | 187 | connection: Redis.getRedisClientOptions('FlowProducer'), |
187 | prefix: this.jobRedisPrefix | 188 | prefix: this.jobRedisPrefix |
188 | }) | 189 | }) |
189 | this.flowProducer.on('error', err => { logger.error('Error in flow producer', { err }) }) | 190 | this.flowProducer.on('error', err => { logger.error('Error in flow producer', { err }) }) |
@@ -196,7 +197,7 @@ class JobQueue { | |||
196 | autorun: false, | 197 | autorun: false, |
197 | concurrency: this.getJobConcurrency(handlerName), | 198 | concurrency: this.getJobConcurrency(handlerName), |
198 | prefix: this.jobRedisPrefix, | 199 | prefix: this.jobRedisPrefix, |
199 | connection: this.getRedisConnection() | 200 | connection: Redis.getRedisClientOptions('Worker') |
200 | } | 201 | } |
201 | 202 | ||
202 | const handler = function (job: Job) { | 203 | const handler = function (job: Job) { |
@@ -236,7 +237,7 @@ class JobQueue { | |||
236 | 237 | ||
237 | private buildQueue (handlerName: JobType) { | 238 | private buildQueue (handlerName: JobType) { |
238 | const queueOptions: QueueOptions = { | 239 | const queueOptions: QueueOptions = { |
239 | connection: this.getRedisConnection(), | 240 | connection: Redis.getRedisClientOptions('Queue'), |
240 | prefix: this.jobRedisPrefix | 241 | prefix: this.jobRedisPrefix |
241 | } | 242 | } |
242 | 243 | ||
@@ -249,7 +250,7 @@ class JobQueue { | |||
249 | private buildQueueScheduler (handlerName: JobType) { | 250 | private buildQueueScheduler (handlerName: JobType) { |
250 | const queueSchedulerOptions: QueueSchedulerOptions = { | 251 | const queueSchedulerOptions: QueueSchedulerOptions = { |
251 | autorun: false, | 252 | autorun: false, |
252 | connection: this.getRedisConnection(), | 253 | connection: Redis.getRedisClientOptions('QueueScheduler'), |
253 | prefix: this.jobRedisPrefix, | 254 | prefix: this.jobRedisPrefix, |
254 | maxStalledCount: 10 | 255 | maxStalledCount: 10 |
255 | } | 256 | } |
@@ -263,7 +264,7 @@ class JobQueue { | |||
263 | private buildQueueEvent (handlerName: JobType) { | 264 | private buildQueueEvent (handlerName: JobType) { |
264 | const queueEventsOptions: QueueEventsOptions = { | 265 | const queueEventsOptions: QueueEventsOptions = { |
265 | autorun: false, | 266 | autorun: false, |
266 | connection: this.getRedisConnection(), | 267 | connection: Redis.getRedisClientOptions('QueueEvent'), |
267 | prefix: this.jobRedisPrefix | 268 | prefix: this.jobRedisPrefix |
268 | } | 269 | } |
269 | 270 | ||
@@ -273,16 +274,6 @@ class JobQueue { | |||
273 | this.queueEvents[handlerName] = queueEvents | 274 | this.queueEvents[handlerName] = queueEvents |
274 | } | 275 | } |
275 | 276 | ||
276 | private getRedisConnection () { | ||
277 | return { | ||
278 | password: CONFIG.REDIS.AUTH, | ||
279 | db: CONFIG.REDIS.DB, | ||
280 | host: CONFIG.REDIS.HOSTNAME, | ||
281 | port: CONFIG.REDIS.PORT, | ||
282 | path: CONFIG.REDIS.SOCKET | ||
283 | } | ||
284 | } | ||
285 | |||
286 | // --------------------------------------------------------------------------- | 277 | // --------------------------------------------------------------------------- |
287 | 278 | ||
288 | async terminate () { | 279 | async terminate () { |
diff --git a/server/lib/redis.ts b/server/lib/redis.ts index b7523492a..4d7947d40 100644 --- a/server/lib/redis.ts +++ b/server/lib/redis.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { createClient, RedisClientOptions, RedisModules } from 'redis' | 1 | import IoRedis, { RedisOptions } from 'ioredis' |
2 | import { exists } from '@server/helpers/custom-validators/misc' | 2 | import { exists } from '@server/helpers/custom-validators/misc' |
3 | import { sha256 } from '@shared/extra-utils' | 3 | import { sha256 } from '@shared/extra-utils' |
4 | import { logger } from '../helpers/logger' | 4 | import { logger } from '../helpers/logger' |
@@ -22,7 +22,7 @@ class Redis { | |||
22 | private static instance: Redis | 22 | private static instance: Redis |
23 | private initialized = false | 23 | private initialized = false |
24 | private connected = false | 24 | private connected = false |
25 | private client: ReturnType<typeof createClient> | 25 | private client: IoRedis |
26 | private prefix: string | 26 | private prefix: string |
27 | 27 | ||
28 | private constructor () { | 28 | private constructor () { |
@@ -33,46 +33,42 @@ class Redis { | |||
33 | if (this.initialized === true) return | 33 | if (this.initialized === true) return |
34 | this.initialized = true | 34 | this.initialized = true |
35 | 35 | ||
36 | this.client = createClient(Redis.getRedisClientOptions()) | ||
37 | this.client.on('error', err => logger.error('Redis Client Error', { err })) | ||
38 | |||
39 | logger.info('Connecting to redis...') | 36 | logger.info('Connecting to redis...') |
40 | 37 | ||
41 | this.client.connect() | 38 | this.client = new IoRedis(Redis.getRedisClientOptions('', { enableAutoPipelining: true })) |
42 | .then(() => { | 39 | this.client.on('error', err => logger.error('Redis failed to connect', { err })) |
43 | logger.info('Connected to redis.') | 40 | this.client.on('connect', () => { |
44 | 41 | logger.info('Connected to redis.') | |
45 | this.connected = true | 42 | |
46 | }).catch(err => { | 43 | this.connected = true |
47 | logger.error('Cannot connect to redis', { err }) | 44 | }) |
48 | process.exit(-1) | 45 | this.client.on('reconnecting', (ms) => { |
49 | }) | 46 | logger.error(`Reconnecting to redis in ${ms}.`) |
47 | }) | ||
48 | this.client.on('close', () => { | ||
49 | logger.error('Connection to redis has closed.') | ||
50 | this.connected = false | ||
51 | }) | ||
52 | |||
53 | this.client.on('end', () => { | ||
54 | logger.error('Connection to redis has closed and no more reconnects will be done.') | ||
55 | }) | ||
50 | 56 | ||
51 | this.prefix = 'redis-' + WEBSERVER.HOST + '-' | 57 | this.prefix = 'redis-' + WEBSERVER.HOST + '-' |
52 | } | 58 | } |
53 | 59 | ||
54 | static getRedisClientOptions () { | 60 | static getRedisClientOptions (connectionName?: string, options: RedisOptions = {}): RedisOptions { |
55 | let config: RedisClientOptions<RedisModules, {}> = { | 61 | return { |
56 | socket: { | 62 | connectionName: [ 'PeerTube', connectionName ].join(''), |
57 | connectTimeout: 20000 // Could be slow since node use sync call to compile PeerTube | 63 | connectTimeout: 20000, // Could be slow since node use sync call to compile PeerTube |
58 | } | 64 | password: CONFIG.REDIS.AUTH, |
59 | } | 65 | db: CONFIG.REDIS.DB, |
60 | 66 | host: CONFIG.REDIS.HOSTNAME, | |
61 | if (CONFIG.REDIS.AUTH) { | 67 | port: CONFIG.REDIS.PORT, |
62 | config = { ...config, password: CONFIG.REDIS.AUTH } | 68 | path: CONFIG.REDIS.SOCKET, |
63 | } | 69 | showFriendlyErrorStack: true, |
64 | 70 | ...options | |
65 | if (CONFIG.REDIS.DB) { | ||
66 | config = { ...config, database: CONFIG.REDIS.DB } | ||
67 | } | 71 | } |
68 | |||
69 | if (CONFIG.REDIS.HOSTNAME && CONFIG.REDIS.PORT) { | ||
70 | config.socket = { ...config.socket, host: CONFIG.REDIS.HOSTNAME, port: CONFIG.REDIS.PORT } | ||
71 | } else { | ||
72 | config.socket = { ...config.socket, path: CONFIG.REDIS.SOCKET } | ||
73 | } | ||
74 | |||
75 | return config | ||
76 | } | 72 | } |
77 | 73 | ||
78 | getClient () { | 74 | getClient () { |
@@ -388,15 +384,15 @@ class Redis { | |||
388 | } | 384 | } |
389 | 385 | ||
390 | private getSet (key: string) { | 386 | private getSet (key: string) { |
391 | return this.client.sMembers(this.prefix + key) | 387 | return this.client.smembers(this.prefix + key) |
392 | } | 388 | } |
393 | 389 | ||
394 | private addToSet (key: string, value: string) { | 390 | private addToSet (key: string, value: string) { |
395 | return this.client.sAdd(this.prefix + key, value) | 391 | return this.client.sadd(this.prefix + key, value) |
396 | } | 392 | } |
397 | 393 | ||
398 | private deleteFromSet (key: string, value: string) { | 394 | private deleteFromSet (key: string, value: string) { |
399 | return this.client.sRem(this.prefix + key, value) | 395 | return this.client.srem(this.prefix + key, value) |
400 | } | 396 | } |
401 | 397 | ||
402 | private deleteKey (key: string) { | 398 | private deleteKey (key: string) { |
@@ -415,11 +411,13 @@ class Redis { | |||
415 | } | 411 | } |
416 | 412 | ||
417 | private async setValue (key: string, value: string, expirationMilliseconds?: number) { | 413 | private async setValue (key: string, value: string, expirationMilliseconds?: number) { |
418 | const options = expirationMilliseconds | 414 | let result |
419 | ? { PX: expirationMilliseconds } | ||
420 | : {} | ||
421 | 415 | ||
422 | const result = await this.client.set(this.prefix + key, value, options) | 416 | if (expirationMilliseconds !== undefined) { |
417 | result = await this.client.set(this.prefix + key, value, 'PX', expirationMilliseconds) | ||
418 | } else { | ||
419 | result = await this.client.set(this.prefix + key, value) | ||
420 | } | ||
423 | 421 | ||
424 | if (result !== 'OK') throw new Error('Redis set result is not OK.') | 422 | if (result !== 'OK') throw new Error('Redis set result is not OK.') |
425 | } | 423 | } |
diff --git a/server/middlewares/cache/shared/api-cache.ts b/server/middlewares/cache/shared/api-cache.ts index abc919339..9e15bf2d6 100644 --- a/server/middlewares/cache/shared/api-cache.ts +++ b/server/middlewares/cache/shared/api-cache.ts | |||
@@ -49,7 +49,7 @@ export class ApiCache { | |||
49 | if (!Redis.Instance.isConnected()) return this.makeResponseCacheable(res, next, key, duration) | 49 | if (!Redis.Instance.isConnected()) return this.makeResponseCacheable(res, next, key, duration) |
50 | 50 | ||
51 | try { | 51 | try { |
52 | const obj = await redis.hGetAll(key) | 52 | const obj = await redis.hgetall(key) |
53 | if (obj?.response) { | 53 | if (obj?.response) { |
54 | return this.sendCachedResponse(req, res, JSON.parse(obj.response), duration) | 54 | return this.sendCachedResponse(req, res, JSON.parse(obj.response), duration) |
55 | } | 55 | } |
@@ -100,8 +100,8 @@ export class ApiCache { | |||
100 | 100 | ||
101 | if (Redis.Instance.isConnected()) { | 101 | if (Redis.Instance.isConnected()) { |
102 | await Promise.all([ | 102 | await Promise.all([ |
103 | redis.hSet(key, 'response', JSON.stringify(value)), | 103 | redis.hset(key, 'response', JSON.stringify(value)), |
104 | redis.hSet(key, 'duration', duration + ''), | 104 | redis.hset(key, 'duration', duration + ''), |
105 | redis.expire(key, duration / 1000) | 105 | redis.expire(key, duration / 1000) |
106 | ]) | 106 | ]) |
107 | } | 107 | } |
@@ -1869,40 +1869,6 @@ | |||
1869 | smtp-server "^3.9.0" | 1869 | smtp-server "^3.9.0" |
1870 | wildstring "1.0.9" | 1870 | wildstring "1.0.9" |
1871 | 1871 | ||
1872 | "@redis/bloom@1.0.2": | ||
1873 | version "1.0.2" | ||
1874 | resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.0.2.tgz#42b82ec399a92db05e29fffcdfd9235a5fc15cdf" | ||
1875 | integrity sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw== | ||
1876 | |||
1877 | "@redis/client@1.3.0": | ||
1878 | version "1.3.0" | ||
1879 | resolved "https://registry.yarnpkg.com/@redis/client/-/client-1.3.0.tgz#c62ccd707f16370a2dc2f9e158a28b7da049fa77" | ||
1880 | integrity sha512-XCFV60nloXAefDsPnYMjHGtvbtHR8fV5Om8cQ0JYqTNbWcQo/4AryzJ2luRj4blveWazRK/j40gES8M7Cp6cfQ== | ||
1881 | dependencies: | ||
1882 | cluster-key-slot "1.1.0" | ||
1883 | generic-pool "3.8.2" | ||
1884 | yallist "4.0.0" | ||
1885 | |||
1886 | "@redis/graph@1.0.1": | ||
1887 | version "1.0.1" | ||
1888 | resolved "https://registry.yarnpkg.com/@redis/graph/-/graph-1.0.1.tgz#eabc58ba99cd70d0c907169c02b55497e4ec8a99" | ||
1889 | integrity sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ== | ||
1890 | |||
1891 | "@redis/json@1.0.4": | ||
1892 | version "1.0.4" | ||
1893 | resolved "https://registry.yarnpkg.com/@redis/json/-/json-1.0.4.tgz#f372b5f93324e6ffb7f16aadcbcb4e5c3d39bda1" | ||
1894 | integrity sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw== | ||
1895 | |||
1896 | "@redis/search@1.1.0": | ||
1897 | version "1.1.0" | ||
1898 | resolved "https://registry.yarnpkg.com/@redis/search/-/search-1.1.0.tgz#7abb18d431f27ceafe6bcb4dd83a3fa67e9ab4df" | ||
1899 | integrity sha512-NyFZEVnxIJEybpy+YskjgOJRNsfTYqaPbK/Buv6W2kmFNaRk85JiqjJZA5QkRmWvGbyQYwoO5QfDi2wHskKrQQ== | ||
1900 | |||
1901 | "@redis/time-series@1.0.3": | ||
1902 | version "1.0.3" | ||
1903 | resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.3.tgz#4cfca8e564228c0bddcdf4418cba60c20b224ac4" | ||
1904 | integrity sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA== | ||
1905 | |||
1906 | "@selderee/plugin-htmlparser2@^0.6.0": | 1872 | "@selderee/plugin-htmlparser2@^0.6.0": |
1907 | version "0.6.0" | 1873 | version "0.6.0" |
1908 | resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.6.0.tgz#27e994afd1c2cb647ceb5406a185a5574188069d" | 1874 | resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.6.0.tgz#27e994afd1c2cb647ceb5406a185a5574188069d" |
@@ -3460,7 +3426,7 @@ clone@^2.0.0: | |||
3460 | resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" | 3426 | resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" |
3461 | integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== | 3427 | integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== |
3462 | 3428 | ||
3463 | cluster-key-slot@1.1.0, cluster-key-slot@^1.1.0: | 3429 | cluster-key-slot@^1.1.0: |
3464 | version "1.1.0" | 3430 | version "1.1.0" |
3465 | resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" | 3431 | resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" |
3466 | integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== | 3432 | integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== |
@@ -5021,11 +4987,6 @@ gauge@^3.0.0: | |||
5021 | strip-ansi "^6.0.1" | 4987 | strip-ansi "^6.0.1" |
5022 | wide-align "^1.1.2" | 4988 | wide-align "^1.1.2" |
5023 | 4989 | ||
5024 | generic-pool@3.8.2: | ||
5025 | version "3.8.2" | ||
5026 | resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.8.2.tgz#aab4f280adb522fdfbdc5e5b64d718d3683f04e9" | ||
5027 | integrity sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg== | ||
5028 | |||
5029 | get-browser-rtc@^1.1.0: | 4990 | get-browser-rtc@^1.1.0: |
5030 | version "1.1.0" | 4991 | version "1.1.0" |
5031 | resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c" | 4992 | resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c" |
@@ -5553,7 +5514,7 @@ invariant@2.2.4: | |||
5553 | dependencies: | 5514 | dependencies: |
5554 | loose-envify "^1.0.0" | 5515 | loose-envify "^1.0.0" |
5555 | 5516 | ||
5556 | ioredis@^5.2.2: | 5517 | ioredis@^5.2.2, ioredis@^5.2.3: |
5557 | version "5.2.3" | 5518 | version "5.2.3" |
5558 | resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.2.3.tgz#d5b37eb13e643241660d6cee4eeb41a026cda8c0" | 5519 | resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.2.3.tgz#d5b37eb13e643241660d6cee4eeb41a026cda8c0" |
5559 | integrity sha512-gQNcMF23/NpvjCaa1b5YycUyQJ9rBNH2xP94LWinNpodMWVUPP5Ai/xXANn/SM7gfIvI62B5CCvZxhg5pOgyMw== | 5520 | integrity sha512-gQNcMF23/NpvjCaa1b5YycUyQJ9rBNH2xP94LWinNpodMWVUPP5Ai/xXANn/SM7gfIvI62B5CCvZxhg5pOgyMw== |
@@ -7865,18 +7826,6 @@ redis-parser@^3.0.0: | |||
7865 | dependencies: | 7826 | dependencies: |
7866 | redis-errors "^1.0.0" | 7827 | redis-errors "^1.0.0" |
7867 | 7828 | ||
7868 | redis@^4.0.1: | ||
7869 | version "4.3.1" | ||
7870 | resolved "https://registry.yarnpkg.com/redis/-/redis-4.3.1.tgz#290532a0c22221e05e991162ac4dca1e1b2ff6da" | ||
7871 | integrity sha512-cM7yFU5CA6zyCF7N/+SSTcSJQSRMEKN0k0Whhu6J7n9mmXRoXugfWDBo5iOzGwABmsWKSwGPTU5J4Bxbl+0mrA== | ||
7872 | dependencies: | ||
7873 | "@redis/bloom" "1.0.2" | ||
7874 | "@redis/client" "1.3.0" | ||
7875 | "@redis/graph" "1.0.1" | ||
7876 | "@redis/json" "1.0.4" | ||
7877 | "@redis/search" "1.1.0" | ||
7878 | "@redis/time-series" "1.0.3" | ||
7879 | |||
7880 | reflect-metadata@^0.1.12: | 7829 | reflect-metadata@^0.1.12: |
7881 | version "0.1.13" | 7830 | version "0.1.13" |
7882 | resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" | 7831 | resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" |
@@ -9574,16 +9523,16 @@ y18n@^5.0.5: | |||
9574 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" | 9523 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" |
9575 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== | 9524 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== |
9576 | 9525 | ||
9577 | yallist@4.0.0, yallist@^4.0.0: | ||
9578 | version "4.0.0" | ||
9579 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" | ||
9580 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== | ||
9581 | |||
9582 | yallist@^2.1.2: | 9526 | yallist@^2.1.2: |
9583 | version "2.1.2" | 9527 | version "2.1.2" |
9584 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" | 9528 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" |
9585 | integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== | 9529 | integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== |
9586 | 9530 | ||
9531 | yallist@^4.0.0: | ||
9532 | version "4.0.0" | ||
9533 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" | ||
9534 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== | ||
9535 | |||
9587 | yaml@^1.10.0: | 9536 | yaml@^1.10.0: |
9588 | version "1.10.2" | 9537 | version "1.10.2" |
9589 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" | 9538 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" |