mirror of
https://github.com/nestjs/nest.git
synced 2026-02-21 23:11:44 +00:00
refactor(microservices): Use options object for JsonSocket constructor
- Replace maxBufferSize parameter with JsonSocketOptions object - Add JsonSocketOptions interface for better extensibility - Update ClientTCP and ServerTCP to pass options object - Update all tests to use new options format Addresses review feedback from @kamilmysliwiec
This commit is contained in:
@@ -113,7 +113,9 @@ export class ClientTCP extends ClientProxy<TcpEvents, TcpStatus> {
|
|||||||
// Pass maxBufferSize only if socketClass is JsonSocket
|
// Pass maxBufferSize only if socketClass is JsonSocket
|
||||||
// For custom socket classes, users should handle maxBufferSize in their own implementation
|
// For custom socket classes, users should handle maxBufferSize in their own implementation
|
||||||
if (this.maxBufferSize !== undefined && this.socketClass === JsonSocket) {
|
if (this.maxBufferSize !== undefined && this.socketClass === JsonSocket) {
|
||||||
return new this.socketClass(socket, this.maxBufferSize);
|
return new this.socketClass(socket, {
|
||||||
|
maxBufferSize: this.maxBufferSize,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return new this.socketClass(socket);
|
return new this.socketClass(socket);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import { TcpSocket } from './tcp-socket';
|
|||||||
|
|
||||||
const DEFAULT_MAX_BUFFER_SIZE = (512 * 1024 * 1024) / 4; // 512 MBs in characters with 4 bytes per character (32-bit)
|
const DEFAULT_MAX_BUFFER_SIZE = (512 * 1024 * 1024) / 4; // 512 MBs in characters with 4 bytes per character (32-bit)
|
||||||
|
|
||||||
|
export interface JsonSocketOptions {
|
||||||
|
maxBufferSize?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class JsonSocket extends TcpSocket {
|
export class JsonSocket extends TcpSocket {
|
||||||
private contentLength: number | null = null;
|
private contentLength: number | null = null;
|
||||||
private buffer = '';
|
private buffer = '';
|
||||||
@@ -14,9 +18,9 @@ export class JsonSocket extends TcpSocket {
|
|||||||
private readonly delimiter = '#';
|
private readonly delimiter = '#';
|
||||||
private readonly maxBufferSize: number;
|
private readonly maxBufferSize: number;
|
||||||
|
|
||||||
constructor(socket: any, maxBufferSize?: number) {
|
constructor(socket: any, options?: JsonSocketOptions) {
|
||||||
super(socket);
|
super(socket);
|
||||||
this.maxBufferSize = maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
|
this.maxBufferSize = options?.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected handleSend(message: any, callback?: (err?: any) => void) {
|
protected handleSend(message: any, callback?: (err?: any) => void) {
|
||||||
|
|||||||
@@ -216,7 +216,9 @@ export class ServerTCP extends Server<TcpEvents, TcpStatus> {
|
|||||||
// Pass maxBufferSize only if socketClass is JsonSocket
|
// Pass maxBufferSize only if socketClass is JsonSocket
|
||||||
// For custom socket classes, users should handle maxBufferSize in their own implementation
|
// For custom socket classes, users should handle maxBufferSize in their own implementation
|
||||||
if (this.maxBufferSize !== undefined && this.socketClass === JsonSocket) {
|
if (this.maxBufferSize !== undefined && this.socketClass === JsonSocket) {
|
||||||
return new this.socketClass(socket, this.maxBufferSize);
|
return new this.socketClass(socket, {
|
||||||
|
maxBufferSize: this.maxBufferSize,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return new this.socketClass(socket);
|
return new this.socketClass(socket);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,13 +43,17 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
describe('custom maxBufferSize', () => {
|
describe('custom maxBufferSize', () => {
|
||||||
it('should use custom maxBufferSize when provided', () => {
|
it('should use custom maxBufferSize when provided', () => {
|
||||||
const customSize = 1000;
|
const customSize = 1000;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
expect(socket['maxBufferSize']).to.equal(customSize);
|
expect(socket['maxBufferSize']).to.equal(customSize);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept data up to custom maxBufferSize', () => {
|
it('should accept data up to custom maxBufferSize', () => {
|
||||||
const customSize = 1000;
|
const customSize = 1000;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
// Account for header length (number + '#')
|
// Account for header length (number + '#')
|
||||||
// For 1000, header is "1000#" = 5 characters
|
// For 1000, header is "1000#" = 5 characters
|
||||||
const headerOverhead = 5;
|
const headerOverhead = 5;
|
||||||
@@ -65,7 +69,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
it('should throw MaxPacketLengthExceededException when exceeding custom maxBufferSize', () => {
|
it('should throw MaxPacketLengthExceededException when exceeding custom maxBufferSize', () => {
|
||||||
const customSize = 1000;
|
const customSize = 1000;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
const largeData = 'x'.repeat(customSize + 1);
|
const largeData = 'x'.repeat(customSize + 1);
|
||||||
const packet = `${largeData.length}#${largeData}`;
|
const packet = `${largeData.length}#${largeData}`;
|
||||||
|
|
||||||
@@ -76,7 +82,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
it('should throw MaxPacketLengthExceededException with correct buffer length', () => {
|
it('should throw MaxPacketLengthExceededException with correct buffer length', () => {
|
||||||
const customSize = 1000;
|
const customSize = 1000;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
const largeData = 'x'.repeat(customSize + 100);
|
const largeData = 'x'.repeat(customSize + 100);
|
||||||
const packet = `${largeData.length}#${largeData}`;
|
const packet = `${largeData.length}#${largeData}`;
|
||||||
// Total buffer size will be: header length (5) + data length (1100) = 1105
|
// Total buffer size will be: header length (5) + data length (1100) = 1105
|
||||||
@@ -95,7 +103,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
describe('chunked data exceeding maxBufferSize', () => {
|
describe('chunked data exceeding maxBufferSize', () => {
|
||||||
it('should throw MaxPacketLengthExceededException when chunked data exceeds limit', () => {
|
it('should throw MaxPacketLengthExceededException when chunked data exceeds limit', () => {
|
||||||
const customSize = 100;
|
const customSize = 100;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
|
|
||||||
// Send data in chunks without a valid header delimiter
|
// Send data in chunks without a valid header delimiter
|
||||||
// This will accumulate in the buffer without being processed
|
// This will accumulate in the buffer without being processed
|
||||||
@@ -112,7 +122,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
it('should clear buffer after throwing MaxPacketLengthExceededException', () => {
|
it('should clear buffer after throwing MaxPacketLengthExceededException', () => {
|
||||||
const customSize = 100;
|
const customSize = 100;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
const largeData = 'x'.repeat(customSize + 1);
|
const largeData = 'x'.repeat(customSize + 1);
|
||||||
const packet = `${largeData.length}#${largeData}`;
|
const packet = `${largeData.length}#${largeData}`;
|
||||||
|
|
||||||
@@ -129,7 +141,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
describe('error handling when maxBufferSize exceeded', () => {
|
describe('error handling when maxBufferSize exceeded', () => {
|
||||||
it(`should emit ${TcpEventsMap.ERROR} event when maxBufferSize is exceeded`, () => {
|
it(`should emit ${TcpEventsMap.ERROR} event when maxBufferSize is exceeded`, () => {
|
||||||
const customSize = 100;
|
const customSize = 100;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
const socketEmitSpy: sinon.SinonSpy<any, any> = sinon.spy(
|
const socketEmitSpy: sinon.SinonSpy<any, any> = sinon.spy(
|
||||||
socket['socket'],
|
socket['socket'],
|
||||||
'emit',
|
'emit',
|
||||||
@@ -147,7 +161,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
it(`should send a FIN packet when maxBufferSize is exceeded`, () => {
|
it(`should send a FIN packet when maxBufferSize is exceeded`, () => {
|
||||||
const customSize = 100;
|
const customSize = 100;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
const socketEndSpy = sinon.spy(socket['socket'], 'end');
|
const socketEndSpy = sinon.spy(socket['socket'], 'end');
|
||||||
|
|
||||||
const largeData = 'x'.repeat(customSize + 1);
|
const largeData = 'x'.repeat(customSize + 1);
|
||||||
@@ -162,7 +178,7 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
describe('edge cases', () => {
|
describe('edge cases', () => {
|
||||||
it('should handle maxBufferSize of 0', () => {
|
it('should handle maxBufferSize of 0', () => {
|
||||||
const socket = new JsonSocket(new Socket(), 0);
|
const socket = new JsonSocket(new Socket(), { maxBufferSize: 0 });
|
||||||
expect(socket['maxBufferSize']).to.equal(0);
|
expect(socket['maxBufferSize']).to.equal(0);
|
||||||
|
|
||||||
const packet = '5#"test"';
|
const packet = '5#"test"';
|
||||||
@@ -173,7 +189,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
it('should handle very large custom maxBufferSize', () => {
|
it('should handle very large custom maxBufferSize', () => {
|
||||||
const veryLargeSize = 10 * 1024 * 1024; // 10MB in characters
|
const veryLargeSize = 10 * 1024 * 1024; // 10MB in characters
|
||||||
const socket = new JsonSocket(new Socket(), veryLargeSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: veryLargeSize,
|
||||||
|
});
|
||||||
expect(socket['maxBufferSize']).to.equal(veryLargeSize);
|
expect(socket['maxBufferSize']).to.equal(veryLargeSize);
|
||||||
|
|
||||||
// Account for header length (number + '#')
|
// Account for header length (number + '#')
|
||||||
@@ -191,7 +209,9 @@ describe('JsonSocket maxBufferSize', () => {
|
|||||||
|
|
||||||
it('should handle maxBufferSize exactly at the limit', () => {
|
it('should handle maxBufferSize exactly at the limit', () => {
|
||||||
const customSize = 100;
|
const customSize = 100;
|
||||||
const socket = new JsonSocket(new Socket(), customSize);
|
const socket = new JsonSocket(new Socket(), {
|
||||||
|
maxBufferSize: customSize,
|
||||||
|
});
|
||||||
// Account for header: "100#" = 4 characters
|
// Account for header: "100#" = 4 characters
|
||||||
// So data can be 100 - 4 = 96 characters to stay at limit
|
// So data can be 100 - 4 = 96 characters to stay at limit
|
||||||
const headerOverhead = 4;
|
const headerOverhead = 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user