Don't let HTTP calls take longer than 5 seconds since we're inside a 30 second lock

This commit is contained in:
James Allen 2016-04-12 17:10:39 +01:00
parent 3c7c318ea0
commit 6c79ab4321
5 changed files with 55 additions and 2 deletions

View file

@ -5,6 +5,11 @@ Metrics = require "./Metrics"
{db, ObjectId} = require("./mongojs")
logger = require "logger-sharelatex"
# We have to be quick with HTTP calls because we're holding a lock that
# expires after 30 seconds. We can't let any errors in the rest of the stack
# hold us up, and need to bail out quickly if there is a problem.
MAX_HTTP_REQUEST_LENGTH = 5000 # 5 seconds
module.exports = PersistenceManager =
getDoc: (project_id, doc_id, callback = (error, lines, version) ->) ->
PersistenceManager.getDocFromWeb project_id, doc_id, (error, lines) ->
@ -37,6 +42,7 @@ module.exports = PersistenceManager =
pass: Settings.apis.web.pass
sendImmediately: true
jar: false
timeout: MAX_HTTP_REQUEST_LENGTH
}, (error, res, body) ->
return callback(error) if error?
if res.statusCode >= 200 and res.statusCode < 300
@ -69,6 +75,7 @@ module.exports = PersistenceManager =
pass: Settings.apis.web.pass
sendImmediately: true
jar: false
timeout: MAX_HTTP_REQUEST_LENGTH
}, (error, res, body) ->
return callback(error) if error?
if res.statusCode >= 200 and res.statusCode < 300

View file

@ -1,6 +1,7 @@
sinon = require "sinon"
chai = require("chai")
chai.should()
expect = chai.expect
async = require "async"
{db, ObjectId} = require "../../../app/js/mongojs"
@ -71,3 +72,30 @@ describe "Flushing a doc to Mongo", ->
it "should not flush the doc to the web api", ->
MockWebApi.setDocumentLines.called.should.equal false
describe "when the web api http request takes a long time", ->
before (done) ->
[@project_id, @doc_id] = [DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]
@timeout = 10000
MockWebApi.insertDoc @project_id, @doc_id, {
lines: @lines
}
sinon.stub MockWebApi, "setDocumentLines", (project_id, doc_id, lines, callback = (error) ->) ->
setTimeout callback, 30000
db.docOps.insert {
doc_id: ObjectId(@doc_id)
version: @version
}, (error) =>
throw error if error?
DocUpdaterClient.preloadDoc @project_id, @doc_id, done
after ->
MockWebApi.setDocumentLines.restore()
it "should return quickly(ish)", (done) ->
start = Date.now()
DocUpdaterClient.flushDoc @project_id, @doc_id, (error, res, doc) =>
res.statusCode.should.equal 500
delta = Date.now() - start
expect(delta).to.be.below 20000
done()

View file

@ -1,6 +1,7 @@
sinon = require "sinon"
chai = require("chai")
chai.should()
expect = chai.expect
{db, ObjectId} = require "../../../app/js/mongojs"
MockWebApi = require "./helpers/MockWebApi"
@ -113,7 +114,22 @@ describe "Getting a document", ->
it "should return 500", ->
@statusCode.should.equal 500
describe "when the web api http request takes a long time", ->
before (done) ->
@timeout = 10000
[@project_id, @doc_id] = [DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]
sinon.stub MockWebApi, "getDocument", (project_id, doc_id, callback = (error, doc) ->) ->
setTimeout callback, 30000
done()
after ->
MockWebApi.getDocument.restore()
it "should return quickly(ish)", (done) ->
start = Date.now()
DocUpdaterClient.getDoc @project_id, @doc_id, (error, res, doc) =>
res.statusCode.should.equal 500
delta = Date.now() - start
expect(delta).to.be.below 20000
done()

View file

@ -41,6 +41,7 @@ describe "PersistenceManager.getDocFromWeb", ->
pass: @pass
sendImmediately: true
jar: false
timeout: 5000
})
.should.equal true

View file

@ -43,6 +43,7 @@ describe "PersistenceManager.setDocInWeb", ->
pass: @pass
sendImmediately: true
jar: false
timeout: 5000
})
.should.equal true