Add basic listening for code problems to Verifier

This commit is contained in:
Nick Winter 2016-04-25 17:03:08 -07:00
parent e8d0ec08cb
commit e96f4651f2
3 changed files with 29 additions and 15 deletions

View file

@ -90,7 +90,7 @@ module.exports = class Angel extends CocoClass
# We have to abort like an infinite loop if we see one of these; they're not really recoverable # We have to abort like an infinite loop if we see one of these; they're not really recoverable
when 'non-user-code-problem' when 'non-user-code-problem'
Backbone.Mediator.publish 'god:non-user-code-problem', problem: event.data.problem, god: @shared.god @publishGodEvent 'non-user-code-problem', problem: event.data.problem
if @shared.firstWorld if @shared.firstWorld
@infinitelyLooped(false, true) # For now, this should do roughly the right thing if it happens during load. @infinitelyLooped(false, true) # For now, this should do roughly the right thing if it happens during load.
else else
@ -109,9 +109,9 @@ module.exports = class Angel extends CocoClass
when 'console-log' when 'console-log'
@log event.data.args... @log event.data.args...
when 'user-code-problem' when 'user-code-problem'
Backbone.Mediator.publish 'god:user-code-problem', problem: event.data.problem, god: @shared.god @publishGodEvent 'user-code-problem', problem: event.data.problem
when 'world-load-progress-changed' when 'world-load-progress-changed'
Backbone.Mediator.publish 'god:world-load-progress-changed', progress: event.data.progress, god: @shared.god @publishGodEvent 'world-load-progress-changed', progress: event.data.progress
unless event.data.progress is 1 or @work.preload or @work.headless or @work.synchronous or @deserializationQueue.length or (@shared.firstWorld and not @shared.spectate) unless event.data.progress is 1 or @work.preload or @work.headless or @work.synchronous or @deserializationQueue.length or (@shared.firstWorld and not @shared.spectate)
@worker.postMessage func: 'serializeFramesSoFar' # Stream it! @worker.postMessage func: 'serializeFramesSoFar' # Stream it!
@ -127,11 +127,10 @@ module.exports = class Angel extends CocoClass
beholdGoalStates: (goalStates, overallStatus, preload=false, totalFrames=undefined, lastFrameHash=undefined) -> beholdGoalStates: (goalStates, overallStatus, preload=false, totalFrames=undefined, lastFrameHash=undefined) ->
return if @aborting return if @aborting
event = goalStates: goalStates, preload: preload, overallStatus: overallStatus, god: @shared.god event = goalStates: goalStates, preload: preload, overallStatus: overallStatus
event.totalFrames = totalFrames if totalFrames? event.totalFrames = totalFrames if totalFrames?
event.lastFrameHash = lastFrameHash if lastFrameHash? event.lastFrameHash = lastFrameHash if lastFrameHash?
Backbone.Mediator.publish 'god:goals-calculated', event @publishGodEvent 'goals-calculated', event
@shared.god.trigger 'goals-calculated', event
@finishWork() if @shared.headless @finishWork() if @shared.headless
beholdWorld: (serialized, goalStates, startFrame, endFrame, streamingWorld) -> beholdWorld: (serialized, goalStates, startFrame, endFrame, streamingWorld) ->
@ -146,10 +145,10 @@ module.exports = class Angel extends CocoClass
return if @aborting or @destroyed return if @aborting or @destroyed
finished = world.frames.length is world.totalFrames finished = world.frames.length is world.totalFrames
firstChangedFrame = world.findFirstChangedFrame @shared.world firstChangedFrame = world.findFirstChangedFrame @shared.world
eventType = if finished then 'god:new-world-created' else 'god:streaming-world-updated' eventType = if finished then 'new-world-created' else 'streaming-world-updated'
if finished if finished
@shared.world = world @shared.world = world
Backbone.Mediator.publish eventType, world: world, firstWorld: @shared.firstWorld, goalStates: goalStates, team: me.team, firstChangedFrame: firstChangedFrame, finished: finished @publishGodEvent eventType, world: world, firstWorld: @shared.firstWorld, goalStates: goalStates, team: me.team, firstChangedFrame: firstChangedFrame, finished: finished
if finished if finished
for scriptNote in @shared.world.scriptNotes for scriptNote in @shared.world.scriptNotes
Backbone.Mediator.publish scriptNote.channel, scriptNote.event Backbone.Mediator.publish scriptNote.channel, scriptNote.event
@ -181,12 +180,17 @@ module.exports = class Angel extends CocoClass
return if @aborting return if @aborting
problem = type: 'runtime', level: 'error', id: 'runtime_InfiniteLoop', message: 'Code never finished. It\'s either really slow or has an infinite loop.' problem = type: 'runtime', level: 'error', id: 'runtime_InfiniteLoop', message: 'Code never finished. It\'s either really slow or has an infinite loop.'
problem.message = 'Escape pressed; code aborted.' if escaped problem.message = 'Escape pressed; code aborted.' if escaped
Backbone.Mediator.publish 'god:user-code-problem', problem: problem, god: @shared.god @publishGodEvent 'user-code-problem', problem: problem
Backbone.Mediator.publish 'god:infinite-loop', firstWorld: @shared.firstWorld, nonUserCodeProblem: nonUserCodeProblem, god: @shared.god @publishGodEvent 'infinite-loop', firstWorld: @shared.firstWorld, nonUserCodeProblem: nonUserCodeProblem
@shared.god.trigger 'infinite-loop', firstWorld: @shared.firstWorld, nonUserCodeProblem: nonUserCodeProblem # For Simulator. TODO: refactor all the god:* Mediator events to be local events.
@reportLoadError() if nonUserCodeProblem @reportLoadError() if nonUserCodeProblem
@fireWorker() @fireWorker()
publishGodEvent: (channel, e) ->
# For Simulator. TODO: refactor all the god:* Mediator events to be local events.
@shared.god.trigger channel, e
e.god = @shared.god
Backbone.Mediator.publish 'god:' + channel, e
reportLoadError: -> reportLoadError: ->
return if me.isAdmin() or /dev=true/.test(window.location?.href ? '') or reportedLoadErrorAlready return if me.isAdmin() or /dev=true/.test(window.location?.href ? '') or reportedLoadErrorAlready
reportedLoadErrorAlready = true reportedLoadErrorAlready = true
@ -320,7 +324,7 @@ module.exports = class Angel extends CocoClass
i = 0 i = 0
while i < work.world.totalFrames while i < work.world.totalFrames
frame = work.world.getFrame i++ frame = work.world.getFrame i++
Backbone.Mediator.publish 'god:world-load-progress-changed', progress: 1, god: @shared.god @publishGodEvent 'world-load-progress-changed', progress: 1
work.world.ended = true work.world.ended = true
system.finish work.world.thangs for system in work.world.systems system.finish work.world.thangs for system in work.world.systems
work.t2 = now() work.t2 = now()

View file

@ -25,6 +25,7 @@ worldUpdatedEventSchema = c.object {required: ['world', 'firstWorld', 'goalState
team: {type: 'string'} team: {type: 'string'}
firstChangedFrame: {type: 'integer', minimum: 0} firstChangedFrame: {type: 'integer', minimum: 0}
finished: {type: 'boolean'} finished: {type: 'boolean'}
god: {type: 'object'}
module.exports = module.exports =
'god:user-code-problem': c.object {required: ['problem', 'god']}, 'god:user-code-problem': c.object {required: ['problem', 'god']},

View file

@ -71,8 +71,8 @@ module.exports = class VerifierTest extends CocoClass
@god.setGoalManager @goalManager @god.setGoalManager @goalManager
register: -> register: ->
@listenToOnce @god, 'infinite-loop', @fail # TODO: have one of these @listenToOnce @god, 'infinite-loop', @fail
@listenToOnce @god, 'user-code-problem', @onUserCodeProblem
@listenToOnce @god, 'goals-calculated', @processSingleGameResults @listenToOnce @god, 'goals-calculated', @processSingleGameResults
@god.createWorld @generateSpellsObject() @god.createWorld @generateSpellsObject()
@updateCallback? state: 'running' @updateCallback? state: 'running'
@ -93,6 +93,15 @@ module.exports = class VerifierTest extends CocoClass
return false if @solution.goals[k] != @goals[k].status return false if @solution.goals[k] != @goals[k].status
return true return true
onUserCodeProblem: (e) ->
console.warning "Found user code problem:", e
onNonUserCodeProblem: (e) ->
console.error "Found non-user-code problem:", e
@error = "Failed due to non-user-code problem: #{JSON.stringify(e)}"
@state = 'error'
@updateCallback? state: @state
fail: (e) -> fail: (e) ->
@error = 'Failed due to infinate loop.' @error = 'Failed due to infinate loop.'
@state = 'error' @state = 'error'