rabbit.js icon indicating copy to clipboard operation
rabbit.js copied to clipboard

callback method for completion of `write` or `publish`

Open mxriverlynn opened this issue 11 years ago • 5 comments

I'd love to see a callback method available on completion of a write or publish method call.

At the moment, I'm doing this:

  var triggerSocket = this.ctx.socket("PUSH");

  console.log("Triggering");

  triggerSocket.connect(jobDest, function(){

    // make the call
    triggerSocket.write(JSON.stringify(trigger));

    // wait til the next tick before closing
    setImmediate(function(){
      triggerSocket.close();
      done();
    });
  });

it works well enough right now... but this makes me really really really really really nervous. i don't want to end up in a situation where this is somehow closing before the message completes... and that seems very likely.

I would prefer something with a callback:

    triggerSocket.write(JSON.stringify(trigger), function(){
      triggerSocket.close();
      done();
    });

mxriverlynn avatar Mar 19 '14 18:03 mxriverlynn

I would prefer something with a callback:

The trouble is that this callback would have to be passed all the way down to the socket, and the underlying library just doesn't support that.

In any case, there are two things working in your favour here. One is that writes don't get buffered at the (rabbit.js) socket, they are given straight to the AMQP client. The second is that Socket#close closes the AMQP client channel, which won't take effect until any writes are flushed. In other words, things should happen in the order that you do them.

That's the theory anyhow. Are you doing the setImmediate() because you ran into a problem with just closing the socket after writing?

squaremo avatar Mar 19 '14 21:03 squaremo

The other thing that occurs to me is that I don't support the Writable event 'finish', which is supposed to be called after 1. the stream has been ended and 2. all writes have been flushed. Consider it on the TODO list.

squaremo avatar Mar 19 '14 21:03 squaremo

regarding your previous question on setImmediate: i'm doing that because without it, the message never gets sent. I don't get any errors or anything, it just doesn't send the message. Adding the setImmediate call works for now... would love to see the finish event available :)

mxriverlynn avatar Mar 24 '14 16:03 mxriverlynn

i'm doing that because without it, the message never gets sent. I don't get any errors or anything

Hrm, so it doesn't work i the way I claim. That may be a problem in amqplib that I need to investigate.

I'm not completely sure I can get 'finish' to work, or not in the expected way. There are buffers in-between a rabbit.js socket and the network socket, and 'finish' does not compose in the sense that 'finish' from the buffer you are dealing with does not mean 'finish' in the operating system buffer.

Just to be clear, does done() exit the program?

squaremo avatar Mar 24 '14 21:03 squaremo

Just to be clear, does done() exit the program?

I ask because exiting, or closing the context, will drop any frames in sockets on the ground. The way to do it is to wait until the socket has closed cleanly:

triggerSocket.close();
triggerSocket.once('close', done);

(This doesn't mean I won't support 'finish', which might be more convenient in some circumstances)

squaremo avatar Mar 31 '14 17:03 squaremo