Skip to content

Commit 1e37fab

Browse files
ihar-tsykalaIhar
andauthored
feat: cache serialization for streams (#4175)
* feat: cache serialization for streams * fix: lint erros --------- Co-authored-by: Ihar <[email protected]>
1 parent 2f814db commit 1e37fab

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

api-gateway/src/helpers/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ export * from './wallet.js';
1515
export * from './decorators/index.js';
1616
export * from './interceptors/index.js';
1717
export * from './entity-owner.js';
18-
export * from './interceptors/utils/index.js';
18+
export * from './interceptors/utils/index.js';
19+
export * from './stream-to-buffer.js';

api-gateway/src/helpers/interceptors/cache.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus } from '@nestjs/common';
1+
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus, StreamableFile } from '@nestjs/common';
22

33
import { Observable, of, switchMap, tap } from 'rxjs';
44

55
//services
66
import { CacheService } from '../cache-service.js';
77
import { Users } from '../users.js';
88

9+
//helpers
10+
import { streamToBuffer } from '../index.js';
11+
912
//utils
1013
import { getCacheKey } from './utils/index.js';
1114

@@ -48,7 +51,11 @@ export class CacheInterceptor implements NestInterceptor {
4851
if (cachedResponse) {
4952
let result = JSON.parse(cachedResponse);
5053

51-
if (result.type === 'buffer') {
54+
if (result.type === 'StreamableFile') {
55+
const buffer = Buffer.from(result.data, 'base64');
56+
result = new StreamableFile(buffer);
57+
}
58+
else if (result.type === 'buffer') {
5259
result = Buffer.from(result.data, 'base64');
5360
} else {
5461
result = result.data;
@@ -74,7 +81,11 @@ export class CacheInterceptor implements NestInterceptor {
7481
result = request.locals;
7582
}
7683

77-
if (Buffer.isBuffer(result)) {
84+
if (response instanceof StreamableFile) {
85+
const buffer = await streamToBuffer(response.getStream());
86+
result = { type: 'StreamableFile', data: buffer.toString('base64') };
87+
}
88+
else if (Buffer.isBuffer(result)) {
7889
result = { type: 'buffer', data: result.toString('base64') };
7990
} else if (typeof response === 'object') {
8091
result = { type: 'json', data: result };
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Readable } from 'stream';
2+
3+
export function streamToBuffer(stream: Readable): Promise<Buffer> {
4+
return new Promise((resolve, reject) => {
5+
const chunks: Buffer[] = [];
6+
stream.on('data', chunk => chunks.push(Buffer.from(chunk)));
7+
stream.on('error', reject);
8+
stream.on('end', () => resolve(Buffer.concat(chunks)));
9+
});
10+
}

0 commit comments

Comments
 (0)