mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-22 16:26:08 +08:00
[client-app] Prevent delta streaming connection from retrying too much
Summary: Before this commit, we would call .close() onError and when the connection closed. We also closed the connection onError, even though NylasLongConnection had also closed it, so we ended up calling close a bunch of times. This would cause us to set a bunch of timeouts to retry unecessarilly. This commit makes it so we ensure there's only one retry timeout and consolidates the logic that calls .close() so we don't call it so many times unnecessarily Test Plan: manual Reviewers: spang, mark, evan Reviewed By: mark, evan Differential Revision: https://phab.nylas.com/D4166
This commit is contained in:
parent
da463c250f
commit
d2cd0db335
|
@ -98,6 +98,7 @@ class NylasLongConnection {
|
||||||
|
|
||||||
onError(error) {
|
onError(error) {
|
||||||
this._onError(error)
|
this._onError(error)
|
||||||
|
this.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
canStart() {
|
canStart() {
|
||||||
|
@ -108,6 +109,7 @@ class NylasLongConnection {
|
||||||
if (!this.canStart()) { return this }
|
if (!this.canStart()) { return this }
|
||||||
if (this._req != null) { return this }
|
if (this._req != null) { return this }
|
||||||
|
|
||||||
|
try {
|
||||||
const accountToken = this._api.accessTokenForAccountId(this._accountId)
|
const accountToken = this._api.accessTokenForAccountId(this._accountId)
|
||||||
const identityToken = (IdentityStore.identity() || {}).token || ''
|
const identityToken = (IdentityStore.identity() || {}).token || ''
|
||||||
if (!accountToken) {
|
if (!accountToken) {
|
||||||
|
@ -138,7 +140,6 @@ class NylasLongConnection {
|
||||||
statusCode: responseStream.statusCode,
|
statusCode: responseStream.statusCode,
|
||||||
})
|
})
|
||||||
this.onError(error)
|
this.onError(error)
|
||||||
this.close()
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -146,7 +147,6 @@ class NylasLongConnection {
|
||||||
responseStream.setEncoding('utf8')
|
responseStream.setEncoding('utf8')
|
||||||
responseStream.on('error', (error) => {
|
responseStream.on('error', (error) => {
|
||||||
this.onError(new APIError({error}))
|
this.onError(new APIError({error}))
|
||||||
this.close()
|
|
||||||
})
|
})
|
||||||
responseStream.on('close', () => this.close())
|
responseStream.on('close', () => this.close())
|
||||||
responseStream.on('end', () => this.close())
|
responseStream.on('end', () => this.close())
|
||||||
|
@ -165,7 +165,6 @@ class NylasLongConnection {
|
||||||
this._req.setSocketKeepAlive(true)
|
this._req.setSocketKeepAlive(true)
|
||||||
this._req.on('error', (error) => {
|
this._req.on('error', (error) => {
|
||||||
this.onError(new APIError({error}))
|
this.onError(new APIError({error}))
|
||||||
this.close()
|
|
||||||
})
|
})
|
||||||
this._req.on('socket', (socket) => {
|
this._req.on('socket', (socket) => {
|
||||||
this.setStatus(Status.Connecting)
|
this.setStatus(Status.Connecting)
|
||||||
|
@ -175,7 +174,6 @@ class NylasLongConnection {
|
||||||
})
|
})
|
||||||
socket.on('error', (error) => {
|
socket.on('error', (error) => {
|
||||||
this.onError(new APIError({error}))
|
this.onError(new APIError({error}))
|
||||||
this.close()
|
|
||||||
})
|
})
|
||||||
socket.on('close', () => this.close())
|
socket.on('close', () => this.close())
|
||||||
socket.on('end', () => this.close())
|
socket.on('end', () => this.close())
|
||||||
|
@ -184,6 +182,12 @@ class NylasLongConnection {
|
||||||
// See https://github.com/nylas/nylas-mail/pull/2004
|
// See https://github.com/nylas/nylas-mail/pull/2004
|
||||||
this._req.end()
|
this._req.end()
|
||||||
return this
|
return this
|
||||||
|
} catch (err) {
|
||||||
|
// start() should not throw any errors synchronously. Any errors should be
|
||||||
|
// asynchronously transmitted to the caller via `onError`
|
||||||
|
setTimeout(() => this.onError(err), 0)
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closeIfDataStops() {
|
closeIfDataStops() {
|
||||||
|
|
|
@ -19,8 +19,9 @@ class DeltaStreamingConnection {
|
||||||
this._account = account
|
this._account = account
|
||||||
this._state = null
|
this._state = null
|
||||||
this._longConnection = null
|
this._longConnection = null
|
||||||
this._writeStateDebounced = _.debounce(this._writeState, 100)
|
this._retryTimeout = null
|
||||||
this._unsubscribers = []
|
this._unsubscribers = []
|
||||||
|
this._writeStateDebounced = _.debounce(this._writeState, 100)
|
||||||
this._backoffScheduler = new ExponentialBackoffScheduler({
|
this._backoffScheduler = new ExponentialBackoffScheduler({
|
||||||
baseDelay: BASE_RETRY_DELAY,
|
baseDelay: BASE_RETRY_DELAY,
|
||||||
maxDelay: MAX_RETRY_DELAY,
|
maxDelay: MAX_RETRY_DELAY,
|
||||||
|
@ -67,11 +68,13 @@ class DeltaStreamingConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
this._clearRetryTimeout()
|
||||||
this._disposeListeners()
|
this._disposeListeners()
|
||||||
this._longConnection.close()
|
this._longConnection.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
end() {
|
end() {
|
||||||
|
this._clearRetryTimeout()
|
||||||
this._disposeListeners()
|
this._disposeListeners()
|
||||||
this._longConnection.end()
|
this._longConnection.end()
|
||||||
}
|
}
|
||||||
|
@ -88,6 +91,11 @@ class DeltaStreamingConnection {
|
||||||
this._unsubscribers = []
|
this._unsubscribers = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_clearRetryTimeout() {
|
||||||
|
clearTimeout(this._retryTimeout)
|
||||||
|
this._retryTimeout = null
|
||||||
|
}
|
||||||
|
|
||||||
_onOnlineStatusChanged = () => {
|
_onOnlineStatusChanged = () => {
|
||||||
if (OnlineStatusStore.isOnline()) {
|
if (OnlineStatusStore.isOnline()) {
|
||||||
this.restart()
|
this.restart()
|
||||||
|
@ -103,7 +111,9 @@ class DeltaStreamingConnection {
|
||||||
this._backoffScheduler.reset()
|
this._backoffScheduler.reset()
|
||||||
}
|
}
|
||||||
if (status === Closed) {
|
if (status === Closed) {
|
||||||
setTimeout(() => this.restart(), this._backoffScheduler.nextDelay());
|
if (this._retryTimeout) { return }
|
||||||
|
this._clearRetryTimeout()
|
||||||
|
this._retryTimeout = setTimeout(() => this.restart(), this._backoffScheduler.nextDelay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +148,6 @@ class DeltaStreamingConnection {
|
||||||
if (!NylasAPIRequest.NonReportableStatusCodes.includes(err.statusCode)) {
|
if (!NylasAPIRequest.NonReportableStatusCodes.includes(err.statusCode)) {
|
||||||
NylasEnv.reportError(err)
|
NylasEnv.reportError(err)
|
||||||
}
|
}
|
||||||
this.close()
|
|
||||||
|
|
||||||
setTimeout(() => this.restart(), this._backoffScheduler.nextDelay());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setCursor = (cursor) => {
|
_setCursor = (cursor) => {
|
||||||
|
@ -160,7 +167,10 @@ class DeltaStreamingConnection {
|
||||||
// Migrate from old storage key
|
// Migrate from old storage key
|
||||||
const oldState = await DatabaseStore.findJSONBlob(`NylasSyncWorker:${this._account.id}`)
|
const oldState = await DatabaseStore.findJSONBlob(`NylasSyncWorker:${this._account.id}`)
|
||||||
if (!oldState) {
|
if (!oldState) {
|
||||||
return {cursor: null, status: null};
|
return {
|
||||||
|
cursor: null,
|
||||||
|
status: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const {deltaCursors = {}, deltaStatus = {}} = oldState
|
const {deltaCursors = {}, deltaStatus = {}} = oldState
|
||||||
|
|
Loading…
Reference in a new issue