mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-09 23:48:36 +01:00
add new service + fix docs links
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"mongoose": "^8.4.0",
|
||||
"nodemailer": "^6.9.13"
|
||||
"nodemailer": "^6.9.13",
|
||||
"redis": "^4.6.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.12.13",
|
||||
|
||||
87
shared/pnpm-lock.yaml
generated
87
shared/pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
||||
nodemailer:
|
||||
specifier: ^6.9.13
|
||||
version: 6.9.13
|
||||
redis:
|
||||
specifier: ^4.6.14
|
||||
version: 4.6.14
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^20.12.13
|
||||
@@ -27,6 +30,35 @@ packages:
|
||||
'@mongodb-js/saslprep@1.1.7':
|
||||
resolution: {integrity: sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==}
|
||||
|
||||
'@redis/bloom@1.2.0':
|
||||
resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==}
|
||||
peerDependencies:
|
||||
'@redis/client': ^1.0.0
|
||||
|
||||
'@redis/client@1.5.16':
|
||||
resolution: {integrity: sha512-X1a3xQ5kEMvTib5fBrHKh6Y+pXbeKXqziYuxOUo1ojQNECg4M5Etd1qqyhMap+lFUOAh8S7UYevgJHOm4A+NOg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@redis/graph@1.1.1':
|
||||
resolution: {integrity: sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==}
|
||||
peerDependencies:
|
||||
'@redis/client': ^1.0.0
|
||||
|
||||
'@redis/json@1.0.6':
|
||||
resolution: {integrity: sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==}
|
||||
peerDependencies:
|
||||
'@redis/client': ^1.0.0
|
||||
|
||||
'@redis/search@1.1.6':
|
||||
resolution: {integrity: sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==}
|
||||
peerDependencies:
|
||||
'@redis/client': ^1.0.0
|
||||
|
||||
'@redis/time-series@1.0.5':
|
||||
resolution: {integrity: sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==}
|
||||
peerDependencies:
|
||||
'@redis/client': ^1.0.0
|
||||
|
||||
'@types/node@20.12.13':
|
||||
resolution: {integrity: sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==}
|
||||
|
||||
@@ -43,6 +75,10 @@ packages:
|
||||
resolution: {integrity: sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==}
|
||||
engines: {node: '>=16.20.1'}
|
||||
|
||||
cluster-key-slot@1.1.2:
|
||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
debug@4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -52,6 +88,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
generic-pool@3.9.0:
|
||||
resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
kareem@2.6.3:
|
||||
resolution: {integrity: sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -115,6 +155,9 @@ packages:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
redis@4.6.14:
|
||||
resolution: {integrity: sha512-GrNg/e33HtsQwNXL7kJT+iNFPSwE1IPmd7wzV3j4f2z0EYxZfZE7FVTmUysgAtqQQtg5NXF5SNLR9OdO/UHOfw==}
|
||||
|
||||
sift@17.1.3:
|
||||
resolution: {integrity: sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==}
|
||||
|
||||
@@ -136,12 +179,41 @@ packages:
|
||||
resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
yallist@4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@mongodb-js/saslprep@1.1.7':
|
||||
dependencies:
|
||||
sparse-bitfield: 3.0.3
|
||||
|
||||
'@redis/bloom@1.2.0(@redis/client@1.5.16)':
|
||||
dependencies:
|
||||
'@redis/client': 1.5.16
|
||||
|
||||
'@redis/client@1.5.16':
|
||||
dependencies:
|
||||
cluster-key-slot: 1.1.2
|
||||
generic-pool: 3.9.0
|
||||
yallist: 4.0.0
|
||||
|
||||
'@redis/graph@1.1.1(@redis/client@1.5.16)':
|
||||
dependencies:
|
||||
'@redis/client': 1.5.16
|
||||
|
||||
'@redis/json@1.0.6(@redis/client@1.5.16)':
|
||||
dependencies:
|
||||
'@redis/client': 1.5.16
|
||||
|
||||
'@redis/search@1.1.6(@redis/client@1.5.16)':
|
||||
dependencies:
|
||||
'@redis/client': 1.5.16
|
||||
|
||||
'@redis/time-series@1.0.5(@redis/client@1.5.16)':
|
||||
dependencies:
|
||||
'@redis/client': 1.5.16
|
||||
|
||||
'@types/node@20.12.13':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
@@ -158,10 +230,14 @@ snapshots:
|
||||
|
||||
bson@6.7.0: {}
|
||||
|
||||
cluster-key-slot@1.1.2: {}
|
||||
|
||||
debug@4.3.4:
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
||||
generic-pool@3.9.0: {}
|
||||
|
||||
kareem@2.6.3: {}
|
||||
|
||||
memory-pager@1.5.0: {}
|
||||
@@ -212,6 +288,15 @@ snapshots:
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
redis@4.6.14:
|
||||
dependencies:
|
||||
'@redis/bloom': 1.2.0(@redis/client@1.5.16)
|
||||
'@redis/client': 1.5.16
|
||||
'@redis/graph': 1.1.1(@redis/client@1.5.16)
|
||||
'@redis/json': 1.0.6(@redis/client@1.5.16)
|
||||
'@redis/search': 1.1.6(@redis/client@1.5.16)
|
||||
'@redis/time-series': 1.0.5(@redis/client@1.5.16)
|
||||
|
||||
sift@17.1.3: {}
|
||||
|
||||
sparse-bitfield@3.0.3:
|
||||
@@ -230,3 +315,5 @@ snapshots:
|
||||
dependencies:
|
||||
tr46: 4.1.1
|
||||
webidl-conversions: 7.0.0
|
||||
|
||||
yallist@4.0.0: {}
|
||||
|
||||
59
shared/services/RedisStreamService.ts
Normal file
59
shared/services/RedisStreamService.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { createClient } from 'redis';
|
||||
import { requireEnv } from '../utilts/requireEnv';
|
||||
|
||||
export type ReadingLoopOptions = {
|
||||
delay?: {
|
||||
base?: number,
|
||||
empty?: number
|
||||
},
|
||||
readBlock?: number,
|
||||
streamName: string
|
||||
}
|
||||
|
||||
export class RedisStreamService {
|
||||
|
||||
private static client = createClient({
|
||||
url: requireEnv("REDIS_URL"),
|
||||
username: requireEnv("REDIS_USERNAME"),
|
||||
password: requireEnv("REDIS_PASSWORD"),
|
||||
});
|
||||
|
||||
static async connect() {
|
||||
await this.client.connect();
|
||||
}
|
||||
|
||||
private static async readingLoop(options: ReadingLoopOptions, processFunction: (content: Record<string, string>) => Promise<any>) {
|
||||
const result = await this.readFromStream(options.streamName, options.readBlock || 2500);
|
||||
if (!result) {
|
||||
await new Promise(r => setTimeout(r, options.delay?.empty || 5000));
|
||||
setTimeout(() => this.readingLoop(options, processFunction), 1);
|
||||
return;
|
||||
}
|
||||
await processFunction(result);
|
||||
await new Promise(r => setTimeout(r, options.delay?.base || 100));
|
||||
setTimeout(() => this.readingLoop(options, processFunction), 1);
|
||||
return;
|
||||
}
|
||||
|
||||
static startReadingLoop(options: ReadingLoopOptions, processFunction: (content: Record<string, string>) => Promise<any>) {
|
||||
this.readingLoop(options, processFunction)
|
||||
}
|
||||
|
||||
private static async readFromStream(streamName: string, readBlock: number) {
|
||||
const result = await this.client.xRead({ id: '0', key: streamName }, { COUNT: 1, BLOCK: readBlock });
|
||||
if (!result) return;
|
||||
if (result.length == 0) return;
|
||||
if (!result[0].messages) return;
|
||||
if (result[0].messages.length == 0) return;
|
||||
const message = result[0].messages[0];
|
||||
await this.client.xDel(streamName, message.id);
|
||||
const content = message.message;
|
||||
return content;
|
||||
}
|
||||
|
||||
static async addToStream(streamName: string, data: Record<string, string>) {
|
||||
const result = await this.client.xAdd(streamName, "*", data);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user