amqplib icon indicating copy to clipboard operation
amqplib copied to clipboard

feat: getCh function to return channel ID

Open sshtel opened this issue 7 years ago • 7 comments

This getter is to return ch value for better channel resource management by users.

sshtel avatar Oct 24 '18 01:10 sshtel

better channel resource management

Can you elaborate on how this helps with better channel resource management?

squaremo avatar Oct 24 '18 07:10 squaremo

When it comes to customized channel pooling, we need to know channel's ID to select which channel should be released or reused.

amqp.node provides good channel create/terminate APIs but still we need more flexible resource management solution to handle a bunch of consumer's request.

Here, we are using a simple array for channel pooling. https://github.com/spearhead-ea/island/blob/f880180a8839bf0f998a2b512e5775f691789fc5/src/services/amqp-channel-pool-service.ts#L23 private idleChannels: Promise<amqp.Channel>[] = [];

When I need to get rid of unused channel from the pool in 'onClose' handler, there is no way to know which channel should be removed. So I used some dirty way by casting Channel object as any to get channel ID.

https://github.com/spearhead-ea/island/blob/f880180a8839bf0f998a2b512e5775f691789fc5/src/services/amqp-channel-pool-service.ts#L121

Plus, It would be great if amqp.node provides embedded channel pool feature in the future. Someone would not agree with it though

sshtel avatar Nov 26 '18 06:11 sshtel

That's a really interesting use! Is object equality not enough for knowing which channel it is? The channel ID may be an unreliable identifier, because the IDs themselves are reused (although not while a channel is still open).

squaremo avatar Nov 26 '18 22:11 squaremo

Comparing object equality was working before I changed the array to Promise array. WAS: private idleChannels: amqp.Channel[] = []; AS-IS: private idleChannels: Promise<amqp.Channel>[] = [];

Promise objects cannot be compared because its internal event count is changing every time.. So I had to use channel ID to know which object is to purge.

I didn't know that channel ID is reused internally. But, yes, it will not that big problem if it is unique when the channel is alive.

sshtel avatar Nov 27 '18 05:11 sshtel

For remind, any thoughts for this MR? @squaremo

sshtel avatar Aug 08 '19 00:08 sshtel

I have to do something similar to this in Rascal in order to support channel pools, but rather than use the actual channel id I decorate the channel object with my own. I think this approach would be safer than using the channel number, which as squaremo said my be reused.

Any objections to adding a uuid property to the channel instead of exposing the underlying channel number?

cressie176 avatar May 15 '22 19:05 cressie176

I've been looking at this again, and have a couple of issues with it...

  1. channel.ch is already public, and not prefixed by an underscore, so hiding it behind a function doesn't add very much
  2. I believe the channel id only unique per connection, so may not be unique enough.

One solution might be to increment a number per connection and return this as the channelId

console.log(channel.getChannelId())
2/33

At least then the channelId would be unique per node process.

An alternative would be to generate a unique id for the connection and pass it as client properties to the broker. This might help debugging too.

5574c9c9-53c8-42f3-9760-82d815da7efa/33

It's a bit ugly though, and means introducing a dependency. Another alternative would be to use socket.localAddress and socket.localPort to identify the connection, in an attempt to replicate the

::1:51470(33)

or maybe even mirror the Admin UI channel name format

::1:51470 -> ::1:5672 (33)

cressie176 avatar Sep 27 '22 14:09 cressie176

Closing as the channel id is already accessible

cressie176 avatar Apr 11 '24 20:04 cressie176