Skip to content

Commit

Permalink
Fix for the #ISS-02 handling null response
Browse files Browse the repository at this point in the history
  • Loading branch information
spidermanja committed Dec 12, 2022
1 parent 223b7f0 commit 6ce32d2
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ node
package-lock.json
#.env
#.npmrc
.settings
tcpdum

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"karma": "^6.3.3",
"karma-jasmine": "^4.0.1",
"karma-requirejs": "^1.1.0",
"node": "^14.20.1",
"node": "^14.21.0",
"requirejs": "^2.3.6"
},
"keywords": [
Expand Down
49 changes: 37 additions & 12 deletions src/main/js/RelpConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,11 @@
* @todo
* 1 - Error management
*
*
*
*/

connect(port, hostname){
async connect(port, hostname){

return new Promise(async(resolve, reject) => {

Expand Down Expand Up @@ -165,6 +167,7 @@
console.log('Connection established');

console.log('Session opening now');
this._socket.setNoDelay = false; // passing false will enable Nagle's algorithm which delay data before it is sent via the network
//Send open session message
let relptRequest = new RelpRequest(RelpConnectionCommand.COMMAND_OPEN, _OFFER); //const
let connectionOpenBatch = new RelpBatch();
Expand Down Expand Up @@ -205,11 +208,20 @@
}


delay(time) {
return new Promise(resolve => setTimeout(resolve, time));
}

/**
* comment:
* @todo application properly handles the close connection when it received the ack packet for each relprequest in the one after the other order. However, sometimes asynchronus opreations /
* tcp protocol or some other reasons If it receives the all responses in one ,
* like, when application sends 2 relprequest mesaage packets one after the other, it may cause some unhanldingpromise warning of null payload. it might need to have to further adjust the parser or our mechanism to tackle.
*
* @returns {Promise}
*/
disconnect(){
async disconnect(){


return new Promise(async(resolve, reject) => {

Expand All @@ -227,8 +239,11 @@
let reqId = connectionCloseBatch.putRequest(relpRequest);
await this.sendBatch(connectionCloseBatch);
let closeSuccess = false;
let closeResponse = connectionCloseBatch.getResponse(reqId);
if(closeResponse._payload._dataLength == 0 ){ // TODO: this is a dirty hack, not an acceptable way.
let closeResponse = await connectionCloseBatch.getResponse(reqId);
//await this.delay(1000)
console.log('CLOSE RESPONSE IS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>', closeResponse)

if(closeResponse == null || closeResponse._payload._dataLength == 0 || closeResponse._payload.byteLength == 0 ){ // TODO: this is a dirty hack, not an acceptable way.
closeSuccess = true;
resolve(true);
}
Expand All @@ -245,7 +260,10 @@
else{
reject('Error occured')
}
})
}).catch(null, () => {
console.log('Error in PROMISE DISCONNECT...')

})
}

/**
Expand All @@ -261,7 +279,7 @@
* @returns {Promise} a commit promise to return rsp for each of the msgs that are in the batch or fail the commit promise.
*
*/
commit(relpBatch){
async commit(relpBatch){

return new Promise(async(resolve, reject) => {

Expand All @@ -270,7 +288,8 @@
}

if(this._state != RelpConnectionState.OPEN){
throw new Error('Session is not in open state, can not commit.'); }
throw new Error('Session is not in open state, can not commit.');
}

this._state = RelpConnectionState.COMMIT;

Expand Down Expand Up @@ -322,7 +341,7 @@
console.log('GET PENDING...');
console.log(this._relpWindow.getPending(txnId));

this.sendRelpRequestAsync(relpRequest);
this.sendRelpRequestAsync(relpRequest);
}

const res = await this.readAcks(relpBatch);
Expand All @@ -333,7 +352,7 @@
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpConnection.sendBatch> exit');
}
}
}
})
}

Expand Down Expand Up @@ -417,7 +436,7 @@
* 2 - Obeservations internal read side buffer increasing -- memory usage stats
* 3 - Effective & Efficient internal buffer management -
*/
readAcks(relpBatch){
async readAcks(relpBatch){
const startTime = Date.now(); // for benchmarking.

return new Promise(async(resolve, reject) => {
Expand All @@ -426,7 +445,7 @@
console.log('relpConnection.readAcks> entry');
}
console.log('readAcks getting batch...', relpBatch);
let byteBuffer = Buffer.alloc(this._rxBufferSize); // No more usage of this, if we handling the socket data buffer directly...
// let byteBuffer = Buffer.alloc(this._rxBufferSize); // No more usage of this, if we handling the socket data buffer directly...

let notComplete = true;

Expand Down Expand Up @@ -476,14 +495,20 @@
let cmd = _PARSER.getCommandString();
let len = _PARSER.getLength();
let pdata = _PARSER.getData();

if(len == 0 && (pdata.byteLength == 0 || pdata == undefined)){
console.log('PData Assigning.....')
pdata = 0

}


let response = new RelpResponse(
_PARSER.getTxnId(),_PARSER.getCommandString(), _PARSER.getLength(), _PARSER.getData()
);

//TODO: This context should update the
console.log(response.toString());
console.log('RESPONSE----',response.toString(), 'len ', len, ' pData ', pdata.byteLength);
console.log('----------------RelpBatch putResponse-------------');
console.log('This is reqID> ',requestId);
relpBatch.putResponse(requestId, response);
Expand Down
40 changes: 33 additions & 7 deletions src/main/js/RelpParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
console.log('relpParser> length: '+ this._responseLengthString);
}
// Handling the special command with txnId 0 which is for serverclose
if(this._responseTxnId == 0 && this._responseLength == 0){
if(this._responseTxnId == 0 && this._responseData == null){
this._isComplete = true;
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser> Special Hint Command: '+this._responseCommandString);
Expand All @@ -150,37 +150,63 @@
}
break;
case 'DATA':

if(this._responseData == null || this._responseData == 'undefined'){
(async () => {
this._responseData = await Buffer.alloc(0); // This for check or change // *** reading waiting for data
})();
//this._responseData = Buffer.alloc(0)
console.log('THIS relpResponse ', this._responseData)
this._isComplete = true;
this._state = relpParserState.NL;
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser-----------------------------------------------------------------------> data: '+ this._responseData.toString());
}
}
if(this._responseLengthLeft > 0) {
if(this._responseData.length > this._responseDataOffset){
// console.log('===== >>>'+this._responseData.length, this._responseLengthLeft);
console.log('===== relpParser....................................................................... >>>'+this._responseData.length, this._responseLengthLeft);
this._responseData.write(String.fromCharCode(b), this._responseDataOffset);
this._responseDataOffset++;
// console.log(this._responseData);
console.log('===== relpParser....................................................................... >>>',this._responseData);
// console.log('relpParser> data b: '+(String.fromCharCode(b)+ ' left: '+ this._responseLengthLeft));
}
this._responseLengthLeft--;

if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser> data b: '+String.fromCharCode(b)+' left '+ this._responseLengthLeft);//TODO: Check
}
}

if(this._responseData.byteLength == 0 && this._responseLengthLeft == 0) {
this._isComplete = true;
this._state = relpParserState.NL;
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser-----------------------------------------------------------------------> data: '+ this._responseData.toString());
}
break;
}
}
if(this._responseLengthLeft == 0) {

//TODO: Check the behaviour

this._state = relpParserState.NL;
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser> data: '+ this._responseData.toString());
}
}
break;
case 'NL':
if(b == '\n'.charCodeAt(0)) {
if(b == '\n'.charCodeAt(0)) { // So this shows when close the connection there is an extra byte following --> '2'.charCodeAt(0)
this._isComplete = true;
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser> newLine: '+ String.fromCharCode(b)+' left '+ this._responseLengthLeft); //TODO: Check
}
}
else if(this._responseData.byteLength == 0 && this._responseLengthString == '0' || this._responseData == undefined){ // 🤔 acceptable???
this._isComplete = true
if(process.env.NODE_ENV == 'RELP_DEBUG'){
console.log('relpParser> newLine: '+ String.fromCharCode(b)+' left '+ this._responseLengthString); //TODO: Check
}
}
else {
throw new Error('relp response parsing failure');
}
Expand Down
5 changes: 1 addition & 4 deletions src/main/js/RelpRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
let sp2 = 1;
let dataLength;
if(this._data == null){
this._dataLength = 0;
dataLength = 0;
}

else {
Expand All @@ -135,9 +135,6 @@
let sp3 = 1;
let data = (this._data == null || this._data == 'undefined' ? 0 : Buffer.byteLength(this._data,'utf8'));
let trailer = 1;
//console.log('CALCULATED LENGTH in RELPREQUEST total >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',(txn + sp1 + command + sp2 + dataLength + sp3 + data + trailer))
console.log('CALCULATED LENGTH in RELPREQUEST Data >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',( dataLength + ' DATA '+ data))

return txn + sp1 + command + sp2 + dataLength + sp3 + data + trailer;
}

Expand Down
23 changes: 23 additions & 0 deletions src/test/js/test-RelpParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ console.log(message.length)
let i = 0;
let parser = new RelpParser();

/*
//TODO: Investigate the data length
while(i < 103){
//console.log(message[i]);
Expand All @@ -26,7 +27,28 @@ console.log(parser.getLength());
console.log(parser.isComplete());
console.log(parser.getData().toString());
console.log("--------RelpParser Result End--------------");
*/

let closeMessage = Buffer.from("2 rsp 0 \n")
let ci = closeMessage.length;

while(i < ci){
//console.log(message[i]);
parser.parse(closeMessage[i]);
i++
}

console.log("--------RelpParser Result--------------");
console.log(parser.getTxnId());
console.log(parser.getCommandString());
console.log(parser.getLength());
console.log(parser.isComplete());
console.log(parser.getData().toString());
console.log("--------RelpParser Result End--------------");



/*
describe('RelpParser TestCases', () => {
it('TXID should be 1', () => {
Expand All @@ -38,3 +60,4 @@ it('Command should be rsp', () => {
expect('rsp').toEqual(parser.getCommandString());
})
*/
5 changes: 2 additions & 3 deletions src/test/js/test-relpCommit.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let cfePort = 1601;
*/

// Coverity Build purpose
/*

async.waterfall(
[
function init(setConnect) {
Expand Down Expand Up @@ -103,7 +103,7 @@ function commit(){
let relpBatch2 = new RelpBatch();

// Tested for the Max Messages approx around 10250 messages works fine, however, more than 10300 might produce RangeError
for(let i = 0; i < 10250; i++){
for(let i = 0; i < 10; i++){
relpBatch2.insert(data2);
}
relpBatch2.insert(data2);
Expand All @@ -122,4 +122,3 @@ function commit(){
return resolve(true);
})
}
*/
Loading

0 comments on commit 6ce32d2

Please sign in to comment.