hitgeek / simple-hl7

A simple library for creating HL7 middleware, based on connect & express.
MIT License
119 stars 59 forks source link

How can I recover from no ACK received (awaitingResponse = true)? #89

Open madebydna opened 1 year ago

madebydna commented 1 year ago

I'm using the TcpClient to send HL7 messages to another server. The client functionality is wrapped with a simple Express API to trigger the sending of messages. Whenever the server doesn't return an ACK for whatever reason, the client is in the awaitingResponse state and won't send another message. At the moment, the only way to recover from this state is to stop and restart the entire express app. Is there another way to recover from it?

Here is a code snippet:

const client = hl7.Server.createTcpClient({
  host: process.env.HL7_LISTENER_HOST,
  port: process.env.HL7_LISTENER_PORT,
  keepalive: true,
});

const app = express();

const sendHandler = (req, res) => {
  try {
    client.send(msg, function (err, ack) {
      if (err) {
        res
          .status(500)
          .json({ message: "Error sending HL7 message", details: err.message })
      } else {
        res.json({ message: 'HL7 message sent successfully', details: ack.log() });
      }
    });
  } catch (err) {
    res
      .status(500)
      .json({ message: "Error sending HL7 message", details: err.message });
  }
};

app.get('/send', sendHandler);

Any pointers would be greatly appreciated.

MKmedicalvalues commented 1 year ago

A very simple (but wasteful) solution would be, to open up a new connection every time you are sending something and closing the connection on receiving the ack.

You could then further improve this aproach by tracking the awaitingResponse again in your wrapper and opening additional connections on demand, then continue using them for some time and close them if they dont get used frequently enough.

hitgeek commented 1 year ago

this isn't currently built into the library, but the way I've handled this in the past is via a timeout. You keep track of when you are waiting for a response, if none is received in a certain period of time, you assume it failed and reset. I can see about adding that to version 4

rohitbaisane commented 1 year ago

@hitgeek When there is unhandled error in parser or error in socket connection we get req and res object as undefined in error middleware. In this case we cannot send even a negative ack because res is undefined. How to handle this situation?

jssuttles commented 1 month ago

@hitgeek speaking of awaitingResponse, isn't it possible to send and await multiple responses and match them to their message control id? Or is HL7 inherently 1 message at a time?

hitgeek commented 1 month ago

(1 message at a time) is the way its implemented here in the tcp (mllp) server/client. that has worked well enough with the systems I've connected to. the file based server/client doesn't handle anything with ACKs, so there isn't this limitation/assumption.

presumably it could be implemented differently, I don't know if the specification is explicit about this or not.

There is also a batch protocol I believe in HL7, but i've never used it, or seen it used in the wild.