@@ -224,6 +224,26 @@ export default class NodeAmqpBroker {
224224 }
225225 }
226226
227+ private async startConsumer ( ch : Channel , consumer : Consumer ) {
228+ const res = await ch . consume ( consumer . queue , ( msg : ConsumeMessage | null ) => {
229+ if ( msg ) {
230+ consumer . handleDelivery ( msg ) ;
231+ } else {
232+ consumer . handleCancel ( true ) ;
233+ }
234+ } ) ;
235+
236+ consumer . tag = res . consumerTag ;
237+ consumer . channel = ch ;
238+
239+ // clear any previous cancel event handler, since this consumer might have
240+ // been rewired to a new channel
241+ consumer . removeAllListeners ( 'cancel' ) ;
242+ consumer . once ( 'cancel' , ( ) => {
243+ this . _channelConsumers . get ( ch ) ?. delete ( consumer ) ;
244+ } ) ;
245+ }
246+
227247 /**
228248 * Recreates consumers on a new channel in the same way as the old one
229249 * @todo properly handle errors, e.g. if the channel is closed when we try to consume (#67)
@@ -233,47 +253,37 @@ export default class NodeAmqpBroker {
233253 if ( ! set || set . size < 1 ) return ;
234254
235255 for ( const consumer of set ) {
236- // FIXME (#67): handle potential errors
237- const res = await newCh . consume ( consumer . queue , ( msg : ConsumeMessage | null ) => {
238- if ( msg && consumer ) {
239- consumer . handleDelivery ( msg ) ;
240- }
241- } ) ;
242-
243- consumer . tag = res . consumerTag ;
244- consumer . channel = newCh ;
245- consumer . resume ( ) ;
256+ try {
257+ await this . startConsumer ( newCh , consumer ) ;
258+ consumer . resume ( ) ;
259+ } catch ( ex : any ) {
260+ set . delete ( consumer ) ;
261+ debug ( 'Failed to rewire consumer' , { queue : consumer . queue , reason : ex } ) ;
262+ }
246263 }
247264
248265 this . _channelConsumers . delete ( ch ) ;
249266 this . _channelConsumers . set ( newCh , set ) ;
250267 }
251268
252- private async _startConsumer ( ch : Channel , queue : string ) : Promise < Consumer > {
269+ private async createConsumer ( ch : Channel , queue : string ) : Promise < Consumer > {
253270 let consumer = new Consumer ( ch , queue ) ;
271+ await this . startConsumer ( ch , consumer ) ;
254272
255- return await ch . consume ( queue , ( msg : ConsumeMessage | null ) => {
256- if ( msg ) {
257- consumer . handleDelivery ( msg ) ;
258- }
259- } ) . then ( ( res : Replies . Consume ) => {
260- consumer . tag = res . consumerTag ;
261-
262- if ( ! this . _channelConsumers . has ( ch ) ) {
263- this . _channelConsumers . set ( ch , new Set ( [ consumer ] ) ) ;
264- } else {
265- const set = this . _channelConsumers . get ( ch ) ;
266- set ! . add ( consumer ) ;
267- }
273+ if ( ! this . _channelConsumers . has ( ch ) ) {
274+ this . _channelConsumers . set ( ch , new Set ( [ consumer ] ) ) ;
275+ } else {
276+ const set = this . _channelConsumers . get ( ch ) ;
277+ set ! . add ( consumer ) ;
278+ }
268279
269- return consumer ;
270- } ) ;
280+ return consumer ;
271281 }
272282
273283 public consume ( queue : string ) : PromiseLike < Consumer > {
274284 if ( ! this . pool ) throw new PeanarAdapterError ( 'Not connected!' ) ;
275285
276- return this . pool . acquireAndRun ( async ch => this . _startConsumer ( ch , queue ) ) ;
286+ return this . pool . acquireAndRun ( async ch => this . createConsumer ( ch , queue ) ) ;
277287 }
278288
279289 public consumeOver ( queues : string [ ] ) {
@@ -283,7 +293,7 @@ export default class NodeAmqpBroker {
283293 return {
284294 queue,
285295 channel : ch ,
286- consumer : await this . _startConsumer ( ch , queue )
296+ consumer : await this . createConsumer ( ch , queue )
287297 } ;
288298 } ) ;
289299 }
0 commit comments