Smarter infinite loop detection vs. web-worker-is-still-loading detection.

This commit is contained in:
Nick Winter 2014-02-27 20:01:27 -08:00
parent ad30130814
commit aef1bc63ba
3 changed files with 22 additions and 11 deletions
app
assets/javascripts/workers
lib
views/play/level/tome

View file

@ -35,13 +35,6 @@ console.error = console.info = console.log;
self.console = console;
importScripts('/javascripts/world.js');
// Since this is run synchronously on the main thread, we might consider splitting it up and sending "ready":
//xhr.onload = function() {
// eval(this.responseText);
// postMessage("ready");
//};
//xhr.open("get", "script.js");
//xhr.send();
// We could do way more from this: http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment
Object.defineProperty(self, "XMLHttpRequest", {
@ -158,3 +151,4 @@ self.addEventListener('message', function(event) {
self[event.data.func](event.data.args);
});
self.postMessage({type: 'worker-initialized'});

View file

@ -44,7 +44,17 @@ module.exports = class God
@createWorker()
createWorker: ->
new Worker '/javascripts/workers/worker_world.js'
worker = new Worker '/javascripts/workers/worker_world.js'
worker.creationTime = new Date()
worker.addEventListener 'message', @onWorkerMessage
worker
onWorkerMessage: (event) =>
worker = event.target
if event.data.type is 'worker-initialized'
#console.log "Worker initialized after", ((new Date()) - worker.creationTime), "ms (before it was needed)"
worker.initialized = true
worker.removeEventListener 'message', @onWorkerMessage
getAngel: ->
freeAngel = null
@ -129,6 +139,7 @@ module.exports = class God
userCodeMap
destroy: ->
worker.removeEventListener 'message', @onWorkerMessage for worker in @workerPool ? []
angel.destroy() for angel in @angels
@dead = true
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
@ -136,6 +147,7 @@ module.exports = class God
@goalManager = null
@fillWorkerPool = null
@simulateWorld = null
@onWorkerMessage = null
#### Bad code for running worlds on main thread (profiling / IE9) ####
simulateWorld: =>
@ -182,7 +194,7 @@ class Angel
@ids[@lastID]
# https://github.com/codecombat/codecombat/issues/81 -- TODO: we need to wait for worker initialization first
infiniteLoopIntervalDuration: 1500000 # check this often (must be more than the others added)
infiniteLoopIntervalDuration: 5000 # check this often (must be more than the others added)
infiniteLoopTimeoutDuration: 1500 # wait this long when we check
abortTimeoutDuration: 500 # give in-process or dying workers this long to give up
constructor: (@god) ->
@ -242,6 +254,9 @@ class Angel
@onWorkerMessage = null
testWorker: =>
unless @worker.initialized
console.warning "Worker", @id, "hadn't even loaded the scripts yet after", @infiniteLoopIntervalDuration, "ms."
return
@worker.postMessage {func: 'reportIn'}
@condemnTimeout = _.delay @condemnWorker, @infiniteLoopTimeoutDuration
@ -254,6 +269,8 @@ class Angel
onWorkerMessage: (event) =>
switch event.data.type
when 'worker-initialized'
console.log "Worker", @id, "initialized after", ((new Date()) - @worker.creationTime), "ms (we had been waiting for it)"
when 'new-world'
@god.beholdWorld @, event.data.serialized, event.data.goalStates
when 'world-load-progress-changed'

View file

@ -328,8 +328,8 @@ module.exports = class SpellView extends View
annotations = []
seenProblemKeys = {}
for aetherProblem, problemIndex in aether.getAllProblems()
continue if aetherProblem.userInfo.key of seenProblemKeys
seenProblemKeys[aetherProblem.userInfo.key] = true
continue if key = aetherProblem.userInfo?.key and key of seenProblemKeys
seenProblemKeys[key] = true if key
@problems.push problem = new Problem aether, aetherProblem, @ace, isCast and problemIndex is 0, isCast
annotations.push problem.annotation if problem.annotation
@aceSession.setAnnotations annotations