简体   繁体   中英

GetDone in ibmmq (Node.js) doesn't stop listener of the queue

I'm using ibmmq module https://github.com/ibm-messaging/mq-mqi-nodejs

I need to get message by CorrelId and then stop listen to the queue.

 async listen(queue: string, messageId?: string, waitInterval?: number) {
    let mqmd = new mq.MQMD()
    let gmo = new mq.MQGMO()
    gmo.Options = this.MQC.MQGMO_NO_SYNCPOINT | this.MQC.MQGMO_WAIT | this.MQC.MQGMO_CONVERT | this.MQC.MQGMO_NO_PROPERTIES | this.MQC.MQGMO_FAIL_IF_QUIESCING
    gmo.MatchOptions = this.MQC.MQMO_MATCH_CORREL_ID
    mqmd.CorrelId = this.hexToBytes(messageId)
    gmo.WaitInterval = this.MQC.MQWI_UNLIMITED
    mq.Get(obj as mq.MQObject, mqmd, gmo, getCB)
  }

And the getCB function:

  getCB(err: mq.MQError, hObj: mq.MQObject, gmo: mq.MQGMO, mqmd: mq.MQMD, buf: Buffer, hConn: mq.MQQueueManager) {
    if (err) {
        ...
    } else {
        ...
        console.log('GetDone:', hObj)
        mq.GetDone(hObj, err => {
          console.log('GetDoneError:', err)
        }) 
    }
  }

I start listening to the queue. Then I put a message with the CorrelId there. The listener get it. I see 'GetDone' in the terminal. And then I put a message with the same CorrelId. And I get that message and Error.

GetDoneError: MQError: GetDone: MQCC = MQCC_FAILED [2] MQRC = MQRC_HOBJ_ERROR [2019]
    at Object.exports.GetDone (/home/apps/connector/node_modules/ibmmq/lib/mqi.js:2316:11)
    at MqiConnector.getCB (/home/apps/connector/src/wmq-mqi-connector.js:206:20)
    at /home/apps/connector/node_modules/ibmmq/lib/mqi.js:2263:14
    at Object.<anonymous> (/home/apps/connector/node_modules/ffi-napi/lib/_foreign_function.js:115:9) {
  mqcc: 2,
  mqccstr: 'MQCC_FAILED',
  mqrc: 2019,
  mqrcstr: 'MQRC_HOBJ_ERROR',
  version: '1.0.0',
  verb: 'GetDone'
}

Looks like the loop with the function getCB didn't stop after GetDone. I get messages with this CorrelId as many times as I send them. And every time I see this error. The listener is still running.

What am I doing wrong?

I suspect that you are calling GetDone twice and the second time hObj is invalid in the call to mq.GetDone .

mq.GetDone(hObj, err => {
          console.log('GetDoneError:', err)
        })

I think you have fallen foul of Node.js asynchronous nature and you have hit a timing issue. IE. the cleanup following GetDone has not completed around the same time as the next message is being retrieved.

The function GetDone seems to be synchronous and can be found in https://github.com/ibm-messaging/mq-mqi-nodejs/blob/3a99e0bbbeb017cc5e8498a59c32967cbd2b27fe/lib/mqi.js

The error appears to come from this snippet in GetDone -

  var userContext = getUserContext(jsObject);
  var err;
  if (!userContext) {
    err = new MQError(MQC.MQCC_FAILED,MQC.MQRC_HOBJ_ERROR,"GetDone");
  } else {
    deleteUserContext(jsObject);
  }

First time through userContext is found and then deleted. Second time round userContext doesn't exist and the error is thrown.

The Sample in the repo - https://github.com/ibm-messaging/mq-mqi-nodejs/blob/72fba926b7010a85ce2a2c6459d2e9c58fa066d7/samples/amqsgeta.js

only calls GetDone in an error condition, ie. when there are either no messages on the queue or there has been a problem getting the next message off the queue.

function getCB(err, hObj, gmo,md,buf, hConn ) {
   // If there is an error, prepare to exit by setting the ok flag to false.
   if (err) {
     if (err.mqrc == MQC.MQRC_NO_MSG_AVAILABLE) {
       console.log("No more messages available.");
     } else {
       console.log(formatErr(err));
       exitCode = 1;
     }
     ok = false;
     // We don't need any more messages delivered, so cause the
     // callback to be deleted after this one has completed.
     mq.GetDone(hObj);
   } else {
     if (md.Format=="MQSTR") {
       console.log("message <%s>", decoder.write(buf));
     } else {
       console.log("binary message: " + buf);
     }
  }
}

Whereas you are calling it when you have retrieved a message. You may need to create a guard that stops you calling it twice.

As for why the second message has been obtained, without an error, you might need to raise an issue on the ibmmq module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM