nodemailer-smtp-pool
Advanced tools
Comparing version 1.0.3 to 1.1.0
{ | ||
"name": "nodemailer-smtp-pool", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "SMTP transport for Nodemailer", | ||
@@ -33,3 +33,3 @@ "main": "src/smtp-pool.js", | ||
"grunt-mocha-test": "^0.12.7", | ||
"mocha": "^2.2.4", | ||
"mocha": "^2.2.5", | ||
"sinon": "^1.14.1", | ||
@@ -36,0 +36,0 @@ "smtp-server": "^1.4.0" |
@@ -42,2 +42,3 @@ # SMTP transport module for Nodemailer | ||
* **maxMessages** (defaults to 100) limits the message count to be sent using a single connection. After maxMessages messages the connection is dropped and a new one is created for the following messages | ||
* **rateLimit** (defaults to `false`) limits the message count to be sent in a second. Once rateLimit is reached, sending is paused until the end of the second. This limit is shared between connections, so if one connection uses up the limit, then other connections are paused as well | ||
@@ -56,4 +57,8 @@ Pooled SMTP transport uses the same options as [SMTP transport](https://github.com/andris9/nodemailer-smtp-transport) with the addition of **maxConnections** and **maxMessages**. | ||
}, | ||
// use up to 5 parallel connections | ||
maxConnections: 5, | ||
maxMessages: 10 | ||
// do not send more than 10 messages per connection | ||
maxMessages: 10, | ||
// no not send more than 5 messages in a second | ||
rateLimit: 5 | ||
})); | ||
@@ -60,0 +65,0 @@ ``` |
@@ -45,2 +45,8 @@ 'use strict'; | ||
this._rateLimit = { | ||
counter: 0, | ||
timeout: null, | ||
waiting: [], | ||
checkpoint: false | ||
}; | ||
this._closed = false; | ||
@@ -75,2 +81,5 @@ this._queue = []; | ||
// clear rate limit timer if it exists | ||
clearTimeout(this._rateLimit.timeout); | ||
// remove all available connections | ||
@@ -136,2 +145,5 @@ for (var i = this._connections.length - 1; i >= 0; i--) { | ||
if (this.options.rateLimit) { | ||
this._rateLimit.counter++; | ||
} | ||
connection.send(element.mail, element.callback); | ||
@@ -144,3 +156,3 @@ }; | ||
SMTPPool.prototype._createConnection = function() { | ||
var connection = new PoolResource(this.options); | ||
var connection = new PoolResource(this); | ||
connection.id = ++this._connectionCounter; | ||
@@ -207,10 +219,57 @@ | ||
/** | ||
* Checks if connections have hit current rate limit and if so, queues the availability callback | ||
* | ||
* @param {Function} callback Callback function to run once rate limiter has been cleared | ||
*/ | ||
SMTPPool.prototype._checkRateLimit = function(callback) { | ||
if (!this.options.rateLimit) { | ||
return callback(); | ||
} | ||
var now = Date.now(); | ||
if (!this._rateLimit.checkpoint) { | ||
this._rateLimit.checkpoint = now; | ||
} | ||
if (this._rateLimit.counter < this.options.rateLimit) { | ||
return callback(); | ||
} | ||
this._rateLimit.waiting.push(callback); | ||
if (this._rateLimit.checkpoint <= now - 1000) { | ||
return this._clearRateLimit(); | ||
} else if (!this._rateLimit.timeout) { | ||
this._rateLimit.timeout = setTimeout(this._clearRateLimit.bind(this), 1000 - (now - this._rateLimit.checkpoint)); | ||
this._rateLimit.checkpoint = now; | ||
} | ||
}; | ||
/** | ||
* Clears current rate limit limitation and runs paused callback | ||
*/ | ||
SMTPPool.prototype._clearRateLimit = function() { | ||
clearTimeout(this._rateLimit.timeout); | ||
this._rateLimit.timeout = null; | ||
this._rateLimit.counter = 0; | ||
this._rateLimit.checkpoint = false; | ||
// resume all paused connections | ||
while (this._rateLimit.waiting.length) { | ||
var cb = this._rateLimit.waiting.shift(); | ||
setImmediate(cb); | ||
} | ||
}; | ||
/** | ||
* Creates an element for the pool | ||
* | ||
* @constructor | ||
* @param {Object} options SMTPPool options | ||
* @param {Object} options SMTPPool instance | ||
*/ | ||
function PoolResource(options) { | ||
function PoolResource(pool) { | ||
EventEmitter.call(this); | ||
this.options = options; | ||
this.pool = pool; | ||
this.options = pool.options; | ||
@@ -327,4 +386,6 @@ this._connection = false; | ||
} else { | ||
this.available = true; | ||
this.emit('available'); | ||
this.pool._checkRateLimit(function() { | ||
this.available = true; | ||
this.emit('available'); | ||
}.bind(this)); | ||
} | ||
@@ -331,0 +392,0 @@ }.bind(this)); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18588
359
138