Merge pull request #2902 from overleaf/bg-handle-clsi-503

handle 503 unavailable from clsi with retry

GitOrigin-RevId: 2b90aadbe93af5007a5a64ff3d2330b2fffbf56f
This commit is contained in:
Brian Gough 2020-06-12 09:27:19 +01:00 committed by Copybot
parent a9fd2de493
commit a078a34e75
4 changed files with 76 additions and 0 deletions

View file

@ -45,6 +45,13 @@ const ClsiManager = {
{ ...options, syncType: 'full' }, { ...options, syncType: 'full' },
callback callback
) )
} else if (status === 'unavailable') {
return ClsiManager.sendRequestOnce(
projectId,
userId,
{ ...options, syncType: 'full', forceNewClsiServer: true },
callback
)
} }
callback(null, status, ...result) callback(null, status, ...result)
} }
@ -173,6 +180,22 @@ const ClsiManager = {
if (options == null) { if (options == null) {
options = {} options = {}
} }
if (options.forceNewClsiServer) {
// Clear clsi cookie, then try again
return ClsiCookieManager.clearServerId(projectId, err => {
if (err) {
return callback(err)
}
options.forceNewClsiServer = false // backend has now been reset
return ClsiManager._sendBuiltRequest(
projectId,
userId,
req,
options,
callback
)
})
}
ClsiFormatChecker.checkRecoursesForProblems( ClsiFormatChecker.checkRecoursesForProblems(
req.compile != null ? req.compile.resources : undefined, req.compile != null ? req.compile.resources : undefined,
(err, validationProblems) => { (err, validationProblems) => {
@ -434,6 +457,8 @@ const ClsiManager = {
callback(null, { compile: { status: 'conflict' } }) callback(null, { compile: { status: 'conflict' } })
} else if (response.statusCode === 423) { } else if (response.statusCode === 423) {
callback(null, { compile: { status: 'compile-in-progress' } }) callback(null, { compile: { status: 'compile-in-progress' } })
} else if (response.statusCode === 503) {
callback(null, { compile: { status: 'unavailable' } })
} else { } else {
callback( callback(
new OError({ new OError({

View file

@ -285,6 +285,10 @@ div.full-size.pdf(ng-controller="PdfController")
strong #{translate("server_error")} strong #{translate("server_error")}
span #{translate("clsi_maintenance")} span #{translate("clsi_maintenance")}
.alert.alert-danger(ng-show="pdf.clsiUnavailable")
strong #{translate("server_error")}
span #{translate("clsi_unavailable")}
.alert.alert-danger(ng-show="pdf.tooRecentlyCompiled") .alert.alert-danger(ng-show="pdf.tooRecentlyCompiled")
strong #{translate("server_error")} strong #{translate("server_error")}
span #{translate("too_recently_compiled")} span #{translate("too_recently_compiled")}

View file

@ -462,6 +462,9 @@ App.controller('PdfController', function(
} else if (response.status === 'clsi-maintenance') { } else if (response.status === 'clsi-maintenance') {
$scope.pdf.view = 'errors' $scope.pdf.view = 'errors'
$scope.pdf.clsiMaintenance = true $scope.pdf.clsiMaintenance = true
} else if (response.status === 'unavailable') {
$scope.pdf.view = 'errors'
$scope.pdf.clsiUnavailable = true
} else if (response.status === 'too-recently-compiled') { } else if (response.status === 'too-recently-compiled') {
$scope.pdf.view = 'errors' $scope.pdf.view = 'errors'
$scope.pdf.tooRecentlyCompiled = true $scope.pdf.tooRecentlyCompiled = true

View file

@ -214,6 +214,50 @@ describe('ClsiManager', function() {
}) })
}) })
describe('with an unavailable response', function() {
beforeEach(function() {
this.ClsiManager.sendRequestOnce = sinon.stub()
this.ClsiManager.sendRequestOnce
.withArgs(this.project_id, this.user_id, {
syncType: 'full',
forceNewClsiServer: true
})
.callsArgWith(3, null, (this.status = 'success'))
this.ClsiManager.sendRequestOnce
.withArgs(this.project_id, this.user_id, {})
.callsArgWith(3, null, 'unavailable')
this.ClsiManager.sendRequest(
this.project_id,
this.user_id,
{},
this.callback
)
})
it('should call the sendRequestOnce method twice', function() {
this.ClsiManager.sendRequestOnce.calledTwice.should.equal(true)
})
it('should call the sendRequestOnce method with forceNewClsiServer:true', function() {
this.ClsiManager.sendRequestOnce
.calledWith(this.project_id, this.user_id, {
forceNewClsiServer: true,
syncType: 'full'
})
.should.equal(true)
})
it('should call the sendRequestOnce method without forceNewClsiServer:true', function() {
this.ClsiManager.sendRequestOnce
.calledWith(this.project_id, this.user_id, {})
.should.equal(true)
})
it('should call the callback with a success status', function() {
this.callback.calledWith(null, this.status).should.equal(true)
})
})
describe('when the resources fail the precompile check', function() { describe('when the resources fail the precompile check', function() {
beforeEach(function() { beforeEach(function() {
this.ClsiFormatChecker.checkRecoursesForProblems = sinon this.ClsiFormatChecker.checkRecoursesForProblems = sinon