Skip to content

Commit

Permalink
Merge pull request #30 from swellstores/feature/add-parallel-requests…
Browse files Browse the repository at this point in the history
…-limit-new

feature: add parallel requests limitAdded  header and tests
  • Loading branch information
DimaZhukovsky authored Dec 11, 2023
2 parents 7452242 + 72aeed1 commit fd58199
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 5 deletions.
3 changes: 3 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ class Client extends EventEmitter {
}
}

// Adding a unique request id to the request
data.$req_id = crypto.randomUUID();

// Capture stacktrace
const error = new Error();

Expand Down
7 changes: 4 additions & 3 deletions lib/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ describe('Client', () => {
expect(serverRequestStub).toHaveBeenCalledWith(
'get',
'url',
{ $data: 'data' },
{ $data: 'data', $req_id: expect.any(String) },
expect.any(Function),
);
});
Expand All @@ -252,6 +252,7 @@ describe('Client', () => {
client: 'id2',
},
$session: 'session-id',
$req_id: expect.any(String),
},
expect.any(Function),
);
Expand All @@ -264,7 +265,7 @@ describe('Client', () => {
expect(serverRequestStub).toHaveBeenCalledWith(
'get',
'url',
{ $data: null },
{ $data: null, $req_id: expect.any(String) },
expect.any(Function),
);
});
Expand Down Expand Up @@ -319,7 +320,7 @@ describe('Client', () => {
expect(respondSpy).toHaveBeenCalledWith(
'get',
'url',
{ $client: 'id', $data: 'data', $key: 'key' },
{ $client: 'id', $data: 'data', $key: 'key', $req_id: expect.any(String) },
{ $status: 200, $data: 'success' },
expect.any(Function),
);
Expand Down
24 changes: 22 additions & 2 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Connection extends EventEmitter {
this.buffer = [];
this.requestBuffer = [];
this.requested = 0;
// Map <string, function> to register callbacks if responses can be received in any order
this.requestCallbacks = new Map();

this.host = host;
this.port = port;
Expand Down Expand Up @@ -112,7 +114,14 @@ class Connection extends EventEmitter {
}
const args = this.requestBuffer[this.requested];
if (args) {
const request = JSON.stringify(args.slice(0, -1));
const requestArr = args.slice(0, -1);
// last argument is the callback
const req_id = requestArr[requestArr.length - 1]?.$req_id;
if (req_id) {
// Register callback in map, if $req_id is specified
this.requestCallbacks.set(req_id, args[args.length - 1]);
}
const request = JSON.stringify(requestArr);
this.stream.write(request + '\n');
this.requested++;
}
Expand Down Expand Up @@ -158,7 +167,17 @@ class Connection extends EventEmitter {
}

const request = this.requestBuffer.shift();
const responder = request && request.pop();

let responder;
const req_id = response?.$req_id;
if (req_id) {
// If $req_id is specified using callback from requestCallbacks map
responder = this.requestCallbacks.get(req_id);
this.requestCallbacks.delete(req_id);
} else {
// Otherwise use callback from last argument of request
responder = request && request.pop();
}

this.requested--;

Expand Down Expand Up @@ -223,6 +242,7 @@ class Connection extends EventEmitter {

this.connected = false;
this.stream = null;
this.requestCallbacks.clear();

if (this.requestBuffer.length > 0) {
this.connect();
Expand Down
51 changes: 51 additions & 0 deletions lib/connection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,56 @@ describe('Connection', () => {
const response = { $push: true };
conn.receiveResponse(JSON.stringify(response));
});

it('should resolve requests in any ordrer, if $req_id is defined', () => {
const conn = new Connection('host', 'port');
conn.connected = true;
conn.stream = {
write: () => {},
};

const productCallback = jest.fn();
const productResult = {
$data: { id: 'prod_1', name: 'Product 1' },
$time: 1,
$status: 200,
$req_id: 'r1',
};
const categoriesCallback = jest.fn();
const categoriesResult = {
$data: {
count: 0,
page_count: 1,
page: 1,
results: [],
},
$time: 1,
$status: 200,
$req_id: 'r2',
};

conn.request(
'get',
'/products/prod_1',
{
$data: {},
$req_id: 'r1',
},
productCallback,
);
conn.request(
'get',
'/categories',
{
$data: {},
$req_id: 'r2',
},
categoriesCallback,
);
conn.receiveResponse(JSON.stringify(categoriesResult));
conn.receiveResponse(JSON.stringify(productResult));
expect(categoriesCallback).toHaveBeenCalledWith(categoriesResult);
expect(productCallback).toHaveBeenCalledWith(productResult);
});
});
});

0 comments on commit fd58199

Please sign in to comment.