Optimizing overall performance under heavy load by temporarily rejecting new sessions that will likely not finish successfully anyway.

This commit is contained in:
Zaid Abdulla committed 2013-08-08 11:24:14 +03:00
1 parent eae6e8b079
commit 4c4b1d630b
1 file changed
+45 -27
+45 -27
View File
@@ -16,6 +16,10 @@ OBJECT_REGEX = /\.$/
INSTANCE_REGEX = /\.[\d]+\.$/ INSTANCE_REGEX = /\.[\d]+\.$/
# Used to reject new TR-069 sessions when under load
holdUntil = Date.now()
applyConfigurations = (currentRequest, taskList) -> applyConfigurations = (currentRequest, taskList) ->
if taskList.length if taskList.length
util.log("#{currentRequest.deviceId}: Presets discrepancy found") util.log("#{currentRequest.deviceId}: Presets discrepancy found")
@@ -129,36 +133,44 @@ updateDevice = (currentRequest, actions, callback) ->
runTask = (currentRequest, task, methodResponse) -> runTask = (currentRequest, task, methodResponse) ->
timeDiff = process.hrtime()
tasks.task(task, methodResponse, (err, status, cwmpResponse, deviceUpdates) -> tasks.task(task, methodResponse, (err, status, cwmpResponse, deviceUpdates) ->
# TODO handle error # TODO handle error
updateDevice(currentRequest, deviceUpdates) updateDevice(currentRequest, deviceUpdates, (err) ->
util.error(err) if err?
switch status timeDiff = process.hrtime(timeDiff)[0] + 1
when tasks.STATUS_FINISHED if timeDiff > 3 # in seconds
db.memcached.del(String(task._id)) # Server under load. Hold new sessions temporarily.
db.tasksCollection.remove({'_id' : mongodb.ObjectID(String(task._id))}, {safe: true}, (err, removed) -> holdUntil = Math.max(Date.now() + timeDiff * 2000, holdUntil)
util.log("#{currentRequest.deviceId}: Completed task #{task.name}(#{task._id})")
nextTask(currentRequest) switch status
) when tasks.STATUS_FINISHED
when tasks.STATUS_FAULT db.memcached.del(String(task._id))
util.log("#{currentRequest.deviceId}: Fault response for task #{task._id}") db.tasksCollection.remove({'_id' : mongodb.ObjectID(String(task._id))}, {safe: true}, (err, removed) ->
db.saveTask(task, (err) -> util.log("#{currentRequest.deviceId}: Completed task #{task.name}(#{task._id})")
# Faulty task. No more work to do until task is deleted. nextTask(currentRequest)
res = tr069.response(null, cwmpResponse) )
writeResponse(currentRequest, res) when tasks.STATUS_FAULT
) util.log("#{currentRequest.deviceId}: Fault response for task #{task._id}")
when tasks.STATUS_PENDING db.saveTask(task, (err) ->
db.saveTask(task, (err) -> # Faulty task. No more work to do until task is deleted.
# task expects CPE confirmation later res = tr069.response(null, cwmpResponse)
nextTask(currentRequest) writeResponse(currentRequest, res)
) )
when tasks.STATUS_STARTED when tasks.STATUS_PENDING
db.updateTask(task, (err) -> db.saveTask(task, (err) ->
res = tr069.response(task._id, cwmpResponse) # task expects CPE confirmation later
writeResponse(currentRequest, res) nextTask(currentRequest)
) )
else when tasks.STATUS_STARTED
throw Error('Unknown task status') db.updateTask(task, (err) ->
res = tr069.response(task._id, cwmpResponse)
writeResponse(currentRequest, res)
)
else
throw Error('Unknown task status')
)
) )
@@ -263,6 +275,12 @@ listener = (httpRequest, httpResponse) ->
if cwmpRequest.methodRequest? if cwmpRequest.methodRequest?
if cwmpRequest.methodRequest.type is 'Inform' if cwmpRequest.methodRequest.type is 'Inform'
if Date.now() < holdUntil
# Ask CPE to retry in 5 mins
res = {code : 503, headers : {'Content-Length' : 0, 'Retry-After' : 300}, data : ''}
writeResponse(currentRequest, res)
return
cwmpResponse.methodResponse = {type : 'InformResponse'} cwmpResponse.methodResponse = {type : 'InformResponse'}
if config.LOG_INFORMS if config.LOG_INFORMS