Skip to content

Commit

Permalink
feat: cache serialization for streams (#4175)
Browse files Browse the repository at this point in the history
* feat: cache serialization for streams

* fix: lint erros

---------

Co-authored-by: Ihar <[email protected]>
  • Loading branch information
ihar-tsykala and Ihar authored Sep 17, 2024
1 parent 2f814db commit 1e37fab
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
3 changes: 2 additions & 1 deletion api-gateway/src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ export * from './wallet.js';
export * from './decorators/index.js';
export * from './interceptors/index.js';
export * from './entity-owner.js';
export * from './interceptors/utils/index.js';
export * from './interceptors/utils/index.js';
export * from './stream-to-buffer.js';
17 changes: 14 additions & 3 deletions api-gateway/src/helpers/interceptors/cache.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus } from '@nestjs/common';
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus, StreamableFile } from '@nestjs/common';

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

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

//helpers
import { streamToBuffer } from '../index.js';

//utils
import { getCacheKey } from './utils/index.js';

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

if (result.type === 'buffer') {
if (result.type === 'StreamableFile') {
const buffer = Buffer.from(result.data, 'base64');
result = new StreamableFile(buffer);
}
else if (result.type === 'buffer') {
result = Buffer.from(result.data, 'base64');
} else {
result = result.data;
Expand All @@ -74,7 +81,11 @@ export class CacheInterceptor implements NestInterceptor {
result = request.locals;
}

if (Buffer.isBuffer(result)) {
if (response instanceof StreamableFile) {
const buffer = await streamToBuffer(response.getStream());
result = { type: 'StreamableFile', data: buffer.toString('base64') };
}
else if (Buffer.isBuffer(result)) {
result = { type: 'buffer', data: result.toString('base64') };
} else if (typeof response === 'object') {
result = { type: 'json', data: result };
Expand Down
10 changes: 10 additions & 0 deletions api-gateway/src/helpers/stream-to-buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Readable } from 'stream';

export function streamToBuffer(stream: Readable): Promise<Buffer> {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
stream.on('data', chunk => chunks.push(Buffer.from(chunk)));
stream.on('error', reject);
stream.on('end', () => resolve(Buffer.concat(chunks)));
});
}

0 comments on commit 1e37fab

Please sign in to comment.