Changes to how tasks are handled to allow better fault handling

This commit is contained in:
Zaid Abdulla committed 2013-02-07 12:07:02 +03:00
1 parent 88c506299c
commit 22ed899657
3 files changed
+123 -48

No files matched your search

+36 -23
View File
@@ -93,27 +93,39 @@ updateDevice = (currentRequest, actions, callback) ->
runTask = (currentRequest, task, methodResponse) -> runTask = (currentRequest, task, methodResponse) ->
cwmpResponse = {} cwmpResponse = {}
actions = tasks.task(task, methodResponse, cwmpResponse) deviceUpdates = {}
status = tasks.task(task, methodResponse, cwmpResponse, deviceUpdates)
updateDevice(currentRequest, actions) updateDevice(currentRequest, deviceUpdates)
if Object.keys(cwmpResponse).length > 0 switch status
when tasks.STATUS_FINISHED
db.memcached.del(String(task._id))
db.tasksCollection.remove({'_id' : mongodb.ObjectID(String(task._id))}, {safe: true}, (err, removed) ->
util.log("#{currentRequest.deviceId}: Completed task #{task.name}(#{task._id})")
nextTask(currentRequest)
)
when tasks.STATUS_FAULT
db.saveTask(task, (err) ->
# Faulty task. No more work to do until task is deleted.
res = tr069.response(null, cwmpResponse)
writeResponse(currentRequest, res)
)
when tasks.STATUS_PENDING
db.saveTask(task, (err) ->
# task expects CPE confirmation later
nextTask(currentRequest)
)
when tasks.STATUS_STARTED
db.updateTask(task, (err) -> db.updateTask(task, (err) ->
res = tr069.response(task._id, cwmpResponse) res = tr069.response(task._id, cwmpResponse)
writeResponse(currentRequest, res) writeResponse(currentRequest, res)
) )
return else
throw Error('Unknown task status')
# Task finished
db.memcached.del(String(task._id))
db.tasksCollection.remove({'_id' : mongodb.ObjectID(String(task._id))}, {safe: true}, (err, removed) ->
util.log("#{currentRequest.deviceId}: Completed task #{task.name}(#{task._id})")
cookies = {}
nextTask(currentRequest, cookies)
)
nextTask = (currentRequest, cookies) -> nextTask = (currentRequest) ->
cur = db.tasksCollection.find({'device' : currentRequest.deviceId}).sort(['timestamp']).limit(1) cur = db.tasksCollection.find({'device' : currentRequest.deviceId}).sort(['timestamp']).limit(1)
cur.nextObject( (err, task) -> cur.nextObject( (err, task) ->
cwmpResponse = {} cwmpResponse = {}
@@ -136,18 +148,17 @@ nextTask = (currentRequest, cookies) ->
) )
else else
# no discrepancy, return empty response # no discrepancy, return empty response
res = tr069.response(null, cwmpResponse, cookies) res = tr069.response(null, cwmpResponse)
writeResponse(currentRequest, res) writeResponse(currentRequest, res)
) )
else else
# no discrepancy, return empty response # no discrepancy, return empty response
res = tr069.response(null, cwmpResponse, cookies) res = tr069.response(null, cwmpResponse)
writeResponse(currentRequest, res) writeResponse(currentRequest, res)
) )
return
else if task.fault? else if task.fault?
# last task was faulty. Do nothing until until task is deleted # last task was faulty. Do nothing until until task is deleted
res = tr069.response(null, cwmpResponse, cookies) res = tr069.response(null, cwmpResponse)
writeResponse(currentRequest, res) writeResponse(currentRequest, res)
else else
util.log("#{currentRequest.deviceId}: Started task #{task.name}(#{task._id})") util.log("#{currentRequest.deviceId}: Started task #{task.name}(#{task._id})")
@@ -244,21 +255,23 @@ else
db.getTask(taskId, (task) -> db.getTask(taskId, (task) ->
if not task if not task
nextTask(currentRequest, cookies) nextTask(currentRequest)
else else
runTask(currentRequest, task, cwmpRequest.methodResponse) runTask(currentRequest, task, cwmpRequest.methodResponse)
) )
else if cwmpRequest.fault? else if cwmpRequest.fault?
taskId = cwmpRequest.id taskId = cwmpRequest.id
util.log("#{currentRequest.deviceId}: Fault response for task #{taskId}") util.log("#{currentRequest.deviceId}: Fault response for task #{taskId}")
db.tasksCollection.update({_id : mongodb.ObjectID(taskId)}, {$set : {fault : cwmpRequest.fault}}, (err) ->
# Faulty task. No more work to do until task is deleted. db.getTask(taskId, (task) ->
res = tr069.response(null, cwmpResponse, cookies) if not task
writeResponse(currentRequest, res) nextTask(currentRequest)
else
runTask(currentRequest, task, cwmpRequest.fault)
) )
else else
# cpe sent empty response. start sending acs requests # cpe sent empty response. start sending acs requests
nextTask(currentRequest, cookies) nextTask(currentRequest)
server.listen config.ACS_PORT, config.ACS_INTERFACE server.listen config.ACS_PORT, config.ACS_INTERFACE
+8
View File
@@ -56,6 +56,14 @@ updateTask = (task, callback) ->
) )
saveTask = (task, callback) ->
task._id = mongodb.ObjectID(String(task._id))
tasksCollection.save(task, (err) ->
callback(err)
)
exports.memcached = memcached exports.memcached = memcached
exports.getTask = getTask exports.getTask = getTask
exports.updateTask = updateTask exports.updateTask = updateTask
exports.saveTask = saveTask
+79 -25
View File
@@ -1,37 +1,64 @@
common = require './common' common = require './common'
BATCH_SIZE = 16 BATCH_SIZE = 16
this.init = (task, methodResponse, cwmpResponse) -> exports.STATUS_QUEUED = STATUS_QUEUED = 0
ret = {} exports.STATUS_STARTED = STATUS_STARTED = 1
exports.STATUS_PENDING = STATUS_PENDING = 2
exports.STATUS_FAULT = STATUS_FAULT = 3
exports.STATUS_FINISHED = STATUS_FINISHED = 4
this.init = (task, methodResponse, cwmpResponse, deviceUpdates) ->
if methodResponse.faultcode?
task.fault = methodResponse
return STATUS_FAULT
if not task.subtask? if not task.subtask?
task.subtask = {'name' : 'getParameterNames', 'parameterPath' : '', 'nextLevel' : false} task.subtask = {'name' : 'getParameterNames', 'parameterPath' : '', 'nextLevel' : false}
if task.subtask.name == 'getParameterNames' if task.subtask.name == 'getParameterNames'
common.extend(ret, this.getParameterNames(task.subtask, methodResponse, cwmpResponse)) status = this.getParameterNames(task.subtask, methodResponse, cwmpResponse, deviceUpdates)
if ret.parameterNames? # task finished if status is STATUS_FINISHED
parameterNames = [] parameterNames = []
for p in ret.parameterNames for p in deviceUpdates.parameterNames
if not common.endsWith(p[0], '.') if not common.endsWith(p[0], '.')
parameterNames.push(p[0]) parameterNames.push(p[0])
task.subtask = {'name' : 'getParameterValues', 'parameterNames' : parameterNames} task.subtask = {'name' : 'getParameterValues', 'parameterNames' : parameterNames}
else if status != STATUS_STARTED
throw Error('Unexpected subtask status')
if task.subtask.name == 'getParameterValues' if task.subtask.name == 'getParameterValues'
common.extend(ret, this.getParameterValues(task.subtask, methodResponse, cwmpResponse)) status = this.getParameterValues(task.subtask, methodResponse, cwmpResponse, deviceUpdates)
if status is STATUS_FINISHED
return STATUS_FINISHED
else if status is not STATUS_STARTED
throw Error('Unexpected subtask status')
ret return STATUS_STARTED
this.getParameterNames = (task, methodResponse, cwmpResponse, deviceUpdates) ->
if methodResponse.faultcode?
task.fault = methodResponse
return STATUS_FAULT
this.getParameterNames = (task, methodResponse, cwmpResponse) ->
if methodResponse.type is 'GetParameterNamesResponse' if methodResponse.type is 'GetParameterNamesResponse'
return {'parameterNames' : methodResponse.parameterList} deviceUpdates.parameterNames = methodResponse.parameterList
else return STATUS_FINISHED
cwmpResponse.methodRequest = { cwmpResponse.methodRequest = {
type : 'GetParameterNames', type : 'GetParameterNames',
parameterPath : task.parameterPath, parameterPath : task.parameterPath,
nextLevel : if task.nextLevel? then task.nextLevel else false nextLevel : if task.nextLevel? then task.nextLevel else false
} }
return return STATUS_STARTED
this.getParameterValues = (task, methodResponse, cwmpResponse, deviceUpdates) ->
if methodResponse.faultcode?
task.fault = methodResponse
return STATUS_FAULT
this.getParameterValues = (task, methodResponse, cwmpResponse) ->
if not task.currentIndex? if not task.currentIndex?
task.currentIndex = 0 task.currentIndex = 0
else if methodResponse.parameterList? else if methodResponse.parameterList?
@@ -40,17 +67,25 @@ this.getParameterValues = (task, methodResponse, cwmpResponse) ->
task.nextIndex = Math.min(task.currentIndex + BATCH_SIZE, task.parameterNames.length) task.nextIndex = Math.min(task.currentIndex + BATCH_SIZE, task.parameterNames.length)
names = task.parameterNames.slice(task.currentIndex, task.nextIndex) names = task.parameterNames.slice(task.currentIndex, task.nextIndex)
if names.length > 0 if methodResponse.type is 'GetParameterValuesResponse'
deviceUpdates.parameterValues = methodResponse.parameterList
if names.length == 0
return STATUS_FINISHED
cwmpResponse.methodRequest = { cwmpResponse.methodRequest = {
type : 'GetParameterValues', type : 'GetParameterValues',
parameterNames : names parameterNames : names
} }
if methodResponse.type is 'GetParameterValuesResponse' return STATUS_STARTED
return {'parameterValues' : methodResponse.parameterList}
return
this.setParameterValues = (task, methodResponse, cwmpResponse, deviceUpdates) ->
if methodResponse.faultcode?
task.fault = methodResponse
return STATUS_FAULT
this.setParameterValues = (task, methodResponse, cwmpResponse) ->
if not task.currentIndex? if not task.currentIndex?
task.currentIndex = 0 task.currentIndex = 0
else if methodResponse.type is 'SetParameterValuesResponse' else if methodResponse.type is 'SetParameterValuesResponse'
@@ -60,29 +95,48 @@ this.setParameterValues = (task, methodResponse, cwmpResponse) ->
task.nextIndex = Math.min(task.currentIndex + BATCH_SIZE, task.parameterValues.length) task.nextIndex = Math.min(task.currentIndex + BATCH_SIZE, task.parameterValues.length)
values = task.parameterValues.slice(task.currentIndex, task.nextIndex) values = task.parameterValues.slice(task.currentIndex, task.nextIndex)
if values.length > 0 if prevValues?
deviceUpdates.parameterValues = prevValues
if values.length == 0
return STATUS_FINISHED
cwmpResponse.methodRequest = { cwmpResponse.methodRequest = {
type : 'SetParameterValues', type : 'SetParameterValues',
parameterList : values parameterList : values
} }
return STATUS_STARTED
if prevValues?
return {'parameterValues' : prevValues}
return
this.reboot = (task, methodResponse, cwmpResponse) -> this.reboot = (task, methodResponse, cwmpResponse, deviceUpdates) ->
if methodResponse.faultcode?
task.fault = methodResponse
return STATUS_FAULT
if methodResponse.type isnt 'RebootResponse' if methodResponse.type isnt 'RebootResponse'
cwmpResponse.methodRequest = { cwmpResponse.methodRequest = {
type : 'Reboot' type : 'Reboot'
} }
return STATUS_STARTED
return STATUS_FINISHED
this.download = (task, methodResponse, cwmpResponse, deviceUpdates) ->
if methodResponse.faultcode?
task.fault = methodResponse
return STATUS_FAULT
this.download = (task, methodResponse, cwmpResponse) ->
if methodResponse.type isnt 'DownloadResponse' if methodResponse.type isnt 'DownloadResponse'
cwmpResponse.methodRequest = { cwmpResponse.methodRequest = {
type : 'Download', type : 'Download',
fileType : task.fileType, fileType : task.fileType,
url : task.url url : task.url
} }
return STATUS_STARTED
exports.task = (task, methodResponse, cwmpResponse) -> return STATUS_FINISHED
return this[task.name](task, methodResponse, cwmpResponse)
exports.task = (task, methodResponse, cwmpResponse, deviceUpdates) ->
return this[task.name](task, methodResponse, cwmpResponse, deviceUpdates)