154 lines
3.6 KiB
TypeScript
154 lines
3.6 KiB
TypeScript
/**
|
|
* Amqp Connection
|
|
*
|
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
|
*
|
|
* This file is part of liza.
|
|
*
|
|
* liza is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Amqp Connection
|
|
*/
|
|
import { AmqpConfig } from '../AmqpPublisher';
|
|
import { EventEmitter } from "events";
|
|
import {
|
|
connect as AmqpConnect,
|
|
Channel,
|
|
Connection,
|
|
} from 'amqplib';
|
|
|
|
|
|
export class AmqpConnection
|
|
{
|
|
/** The amqp connection */
|
|
private _conn?: Connection;
|
|
|
|
/** The amqp channel */
|
|
private _channel?: Channel;
|
|
|
|
|
|
/**
|
|
* Amqp Connection
|
|
*
|
|
* @param _conf - amqp configuration
|
|
* @param _emitter - event emitter instance
|
|
*/
|
|
constructor(
|
|
private readonly _conf: AmqpConfig,
|
|
private readonly _emitter: EventEmitter,
|
|
) {}
|
|
|
|
|
|
/**
|
|
* Initialize connection
|
|
*/
|
|
connect(): Promise<void>
|
|
{
|
|
return AmqpConnect( this._conf )
|
|
.then( conn =>
|
|
{
|
|
this._conn = conn;
|
|
|
|
/** If there is an error, attempt to reconnect
|
|
* Only hook this once because it will be re-hooked on each
|
|
* successive successful connection
|
|
*/
|
|
this._conn.once( 'error', e =>
|
|
{
|
|
this._emitter.emit( 'amqp-conn-error', e );
|
|
this._reconnect();
|
|
} );
|
|
|
|
return this._conn.createChannel();
|
|
} )
|
|
.then( ( ch: Channel ) =>
|
|
{
|
|
this._channel = ch;
|
|
|
|
this._channel.assertExchange(
|
|
this._conf.exchange,
|
|
'fanout',
|
|
{ durable: true }
|
|
);
|
|
} );
|
|
}
|
|
|
|
|
|
/**
|
|
* Attempt to re-establish the connection
|
|
*
|
|
* @param retry_count - the number of retries attempted
|
|
*/
|
|
private _reconnect( retry_count: number = 0 ): void
|
|
{
|
|
if ( retry_count >= this._conf.retries )
|
|
{
|
|
this._emitter.emit(
|
|
'error',
|
|
new Error( 'Could not re-establish AMQP connection.' )
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
this._emitter.emit( 'amqp-reconnect' );
|
|
|
|
this.connect()
|
|
.then( _ => { this._emitter.emit( 'amqp-reconnected' ) } )
|
|
.catch( _ =>
|
|
{
|
|
const wait_ms = this._conf.retry_wait;
|
|
setTimeout( () => this._reconnect( ++retry_count ), wait_ms );
|
|
} );
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the exchange to publish to
|
|
*
|
|
* @return exchange name
|
|
*/
|
|
getExchangeName(): string
|
|
{
|
|
return this._conf.exchange;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the amqp channel
|
|
*
|
|
* @return exchange name
|
|
*/
|
|
getAmqpChannel(): Channel | undefined
|
|
{
|
|
if ( !this._channel )
|
|
{
|
|
this._reconnect();
|
|
}
|
|
|
|
return this._channel;
|
|
}
|
|
|
|
|
|
/**
|
|
* Close the amqp conenction
|
|
*/
|
|
close(): void
|
|
{
|
|
if ( this._conn )
|
|
{
|
|
this._conn.close.bind(this._conn);
|
|
}
|
|
}
|
|
} |