mirror of
https://github.com/dawidd6/action-send-mail.git
synced 2026-10-12 02:42:27 +07:00
node_modules: update (#344)
Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
This commit is contained in:
1 parent
b099186883
commit
6e88c72525
63 files changed
+2863
-1227
No files matched your search
+106
-17
@@ -90,6 +90,8 @@ class PoolResource extends node_events_1.EventEmitter {
|
||||
this.messages = 0;
|
||||
this.available = true;
|
||||
this._failed = false;
|
||||
this._sending = false;
|
||||
this._idleTimer = false;
|
||||
}
|
||||
/**
|
||||
* Emits 'error' for the first failure only. A dead resource can report the same failure more
|
||||
@@ -109,7 +111,9 @@ class PoolResource extends node_events_1.EventEmitter {
|
||||
* @param callback Callback function to run once the connection is established or failed
|
||||
*/
|
||||
connect(callback) {
|
||||
this.pool.getSocket(this.options, (err, socketOptions) => {
|
||||
// the proxy handshake, if any, counts against connectionTimeout as well
|
||||
const connectStartedAt = Date.now();
|
||||
this.pool.getSocket(Object.assign({}, this.options, { connectStartedAt }), (err, socketOptions) => {
|
||||
if (err) {
|
||||
// nothing was connected, so no 'close' event is coming that would free the
|
||||
// slot this resource holds in the pool, report the failure the way a failed
|
||||
@@ -131,7 +135,21 @@ class PoolResource extends node_events_1.EventEmitter {
|
||||
options = Object.assign((0, index_js_2.assign)(false, options), socketOptions);
|
||||
}
|
||||
this.connection = new index_js_1.default(options);
|
||||
this.connection.on('error', err => {
|
||||
this.connection._connectStartedAt = connectStartedAt;
|
||||
this.connection.on('error', (err) => {
|
||||
if (this._sending) {
|
||||
// the send callback gets the same error and decides what it means for the message
|
||||
return;
|
||||
}
|
||||
if (this._connected && errors.isTransientError(err)) {
|
||||
// the server ended a connection that had nothing in flight, usually after it
|
||||
// was idle for a while. The 'end' that follows closes this resource
|
||||
this.logger.info({
|
||||
tnx: 'pool',
|
||||
cid: this.id
|
||||
}, 'Connection #%s was closed by the server: %s', this.id, err.message);
|
||||
return;
|
||||
}
|
||||
this._fail(err);
|
||||
if (returned) {
|
||||
return;
|
||||
@@ -209,9 +227,39 @@ class PoolResource extends node_events_1.EventEmitter {
|
||||
if (mail.data.requireTLSExtensionEnabled) {
|
||||
envelope.requireTLSExtensionEnabled = mail.data.requireTLSExtensionEnabled;
|
||||
}
|
||||
this.connection.send(envelope, mail.message.createReadStream(), (err, info) => {
|
||||
this._sending = true;
|
||||
// a connection that sent messages before may have been dropped by the server in between
|
||||
const reused = this.messages > 0;
|
||||
const messageStream = mail.message.createReadStream();
|
||||
this.connection.send(envelope, messageStream, (err, info) => {
|
||||
this._sending = false;
|
||||
this.messages++;
|
||||
if (err) {
|
||||
if (reused && messageStream.readableDidRead === false && errors.isTransientError(err)) {
|
||||
// Not a byte of the message was sent, so it can go out over another
|
||||
// connection. The pool requeues the message when this resource closes
|
||||
this.logger.info({
|
||||
tnx: 'pool',
|
||||
cid: this.id,
|
||||
messageId
|
||||
}, 'Connection #%s was closed by the server before message %s was sent: %s', this.id, messageId, err.message);
|
||||
this.connection.close();
|
||||
return;
|
||||
}
|
||||
if ((err.code === errors.EENVELOPE || err.code === errors.EMESSAGE) &&
|
||||
err.responseCode !== 421 &&
|
||||
!this.connection._destroyed) {
|
||||
// The server refused this message, the connection itself is fine. Reset the
|
||||
// session and keep using it instead of opening a new one
|
||||
this.connection.reset(resetErr => {
|
||||
if (resetErr) {
|
||||
this.connection.close();
|
||||
return;
|
||||
}
|
||||
this._release();
|
||||
});
|
||||
return callback(err);
|
||||
}
|
||||
this.connection.close();
|
||||
this._fail(err);
|
||||
return callback(err);
|
||||
@@ -221,28 +269,69 @@ class PoolResource extends node_events_1.EventEmitter {
|
||||
to: envelope.to
|
||||
};
|
||||
info.messageId = messageId;
|
||||
setImmediate(() => {
|
||||
if (this.messages >= this.options.maxMessages) {
|
||||
const err = new Error('Resource exhausted');
|
||||
err.code = errors.EMAXLIMIT;
|
||||
this.connection.close();
|
||||
this._fail(err);
|
||||
}
|
||||
else {
|
||||
this.pool._checkRateLimit(() => {
|
||||
this.available = true;
|
||||
this.emit('available');
|
||||
});
|
||||
}
|
||||
});
|
||||
setImmediate(() => this._release());
|
||||
callback(null, info);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Makes the connection available for the next message, or closes it once it has sent
|
||||
* maxMessages messages
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
_release() {
|
||||
if (this.messages >= this.options.maxMessages) {
|
||||
const err = new Error('Resource exhausted');
|
||||
err.code = errors.EMAXLIMIT;
|
||||
this.connection.close();
|
||||
this._fail(err);
|
||||
return;
|
||||
}
|
||||
this.pool._checkRateLimit(() => {
|
||||
this.available = true;
|
||||
this._startIdleTimer();
|
||||
this.emit('available');
|
||||
});
|
||||
}
|
||||
/** @internal */
|
||||
_startIdleTimer() {
|
||||
if (!this.options.idleTimeout || this.options.idleTimeout < 0) {
|
||||
return;
|
||||
}
|
||||
// one timer per connection, restarted every time the connection becomes available. A
|
||||
// connection that is busy when it fires is simply not closed
|
||||
if (this._idleTimer && typeof this._idleTimer.refresh === 'function') {
|
||||
this._idleTimer.refresh();
|
||||
return;
|
||||
}
|
||||
clearTimeout(this._idleTimer);
|
||||
this._idleTimer = setTimeout(() => {
|
||||
if (!this.available) {
|
||||
return;
|
||||
}
|
||||
this.logger.debug({
|
||||
tnx: 'pool',
|
||||
cid: this.id
|
||||
}, 'Closing connection #%s after it was idle for %sms', this.id, this.options.idleTimeout);
|
||||
// not handed another message while it says goodbye
|
||||
this.available = false;
|
||||
this.connection.quit();
|
||||
}, this.options.idleTimeout);
|
||||
if (typeof this._idleTimer.unref === 'function') {
|
||||
this._idleTimer.unref();
|
||||
}
|
||||
}
|
||||
/** @internal */
|
||||
_stopIdleTimer() {
|
||||
clearTimeout(this._idleTimer);
|
||||
this._idleTimer = false;
|
||||
}
|
||||
/**
|
||||
* Closes the connection
|
||||
*/
|
||||
close() {
|
||||
this._connected = false;
|
||||
this._stopIdleTimer();
|
||||
if (this.auth && this.auth.oauth2) {
|
||||
this.auth.oauth2.removeAllListeners();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user