Created
August 10, 2011 01:12
-
-
Save aseemk/1135758 to your computer and use it in GitHub Desktop.
Streamline bug: nested switch statements somehow mess up sync flow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# async simulation helper: | |
async = (_) -> | |
setTimeout _, 500 | |
# assume we're dealing with a status change event | |
type = 'event' | |
kind = 'statusChange' | |
# assume we initially have no user or target | |
user = null | |
target = null | |
getUser = (_) -> | |
console.log 'fetching user...' | |
async _ | |
console.log 'user fetched.' | |
return {} | |
getTarget = (_) -> | |
console.log 'fetching target...' | |
async _ | |
console.log 'target fetched.' | |
return {} | |
METHOD = (_) -> | |
console.log "BEGIN" | |
if type is 'comment' | |
user or= getUser _ | |
target or= getTarget _ | |
else if type is 'event' | |
if kind is 'statusChange' | |
user or= getUser _ | |
target or= getTarget _ | |
else if kind is 'follow' | |
user or= getUser _ | |
target or= getTarget _ | |
console.log "END" | |
METHOD _ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var METHOD, async, getTarget, getUser, kind, target, type, user; | |
async = function(_) { | |
return setTimeout(_, 500); | |
}; | |
type = 'event'; | |
kind = 'statusChange'; | |
user = null; | |
target = null; | |
getUser = function(_) { | |
console.log('fetching user...'); | |
async(_); | |
console.log('user fetched.'); | |
return {}; | |
}; | |
getTarget = function(_) { | |
console.log('fetching target...'); | |
async(_); | |
console.log('target fetched.'); | |
return {}; | |
}; | |
METHOD = function(_) { | |
console.log("BEGIN"); | |
if (type === 'comment') { | |
user || (user = getUser(_)); | |
target || (target = getTarget(_)); | |
} else if (type === 'event') { | |
if (kind === 'statusChange') { | |
user || (user = getUser(_)); | |
target || (target = getTarget(_)); | |
} else if (kind === 'follow') { | |
user || (user = getUser(_)); | |
target || (target = getTarget(_)); | |
} | |
} | |
return console.log("END"); | |
}; | |
METHOD(_); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BEGIN | |
fetching user... | |
user fetched. | |
fetching target... | |
target fetched. | |
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var __global = typeof global !== 'undefined' ? global : window; | |
function __cb(_, fn){ var ctx = __global.__context; return function(err, result){ __global.__context = ctx; if (err) return _(err); try { return fn(null, result); } catch (ex) { return __propagate(_, ex); } } } | |
function __future(fn, args, i){ var done, err, result; var cb = function(e, r){ done = true; err = e, result = r; }; args = Array.prototype.slice.call(args); args[i] = function(e, r){ cb(e, r); }; fn.apply(this, args); return function(_){ if (done) _.call(this, err, result); else cb = _.bind(this); } .bind(this); } | |
function __propagate(_, err){ try { _(err); } catch (ex) { __trap(ex); } } | |
function __trap(err){ if (err) { if (__global.__context && __global.__context.errorHandler) __global.__context.errorHandler(err); else console.error("UNCAUGHT EXCEPTION: " + err.message + "\n" + err.stack); } } | |
(function __main(_) { | |
var METHOD, async, getTarget, getUser, kind, target, type, user; | |
/* 2 */ async = function __1(_) { | |
if (!_) { | |
return __future(__1, arguments, 0); | |
} | |
; | |
/* 3 */ return setTimeout(_, 500); | |
}; | |
/* 5 */ type = "event"; | |
/* 6 */ kind = "statusChange"; | |
/* 7 */ user = null; | |
/* 8 */ target = null; | |
/* 9 */ getUser = function __2(_) { | |
if (!_) { | |
return __future(__2, arguments, 0); | |
} | |
; | |
/* 10 */ console.log("fetching user..."); | |
/* 11 */ return async(__cb(_, function() { | |
/* 12 */ console.log("user fetched."); | |
/* 13 */ return _(null, { | |
}); | |
})); | |
}; | |
/* 15 */ getTarget = function __3(_) { | |
if (!_) { | |
return __future(__3, arguments, 0); | |
} | |
; | |
/* 16 */ console.log("fetching target..."); | |
/* 17 */ return async(__cb(_, function() { | |
/* 18 */ console.log("target fetched."); | |
/* 19 */ return _(null, { | |
}); | |
})); | |
}; | |
/* 21 */ METHOD = function __4(_) { | |
if (!_) { | |
return __future(__4, arguments, 0); | |
} | |
; | |
/* 22 */ console.log("BEGIN"); | |
(function(__break) { | |
/* 23 */ switch (type) { | |
/* 24 */ case "comment": | |
/* 24 */ return (function(_) { | |
var __1 = user; | |
/* 25 */ if (__1) { | |
return _(null, __1); | |
} | |
; | |
return getUser(__cb(_, function(__0, __3) { | |
/* 25 */ var __2 = (user = __3); | |
/* 25 */ return _(null, __2); | |
})); | |
})(__cb(_, function() { | |
return (function(_) { | |
var __2 = target; | |
/* 26 */ if (__2) { | |
return _(null, __2); | |
} | |
; | |
return getTarget(__cb(_, function(__0, __4) { | |
/* 26 */ var __3 = (target = __4); | |
/* 26 */ return _(null, __3); | |
})); | |
})(__cb(_, function() { | |
return __break(); | |
})); | |
})); | |
case "event": | |
(function(__break) { | |
/* 28 */ switch (kind) { | |
/* 28 */ case "statusChange": | |
return (function(_) { | |
/* 29 */ var __3 = user; | |
/* 30 */ if (__3) { | |
/* 30 */ return _(null, __3); | |
} | |
/* 31 */ ; | |
return getUser(__cb(_, function(__0, __5) { | |
var __4 = (user = __5); | |
return _(null, __4); | |
})); | |
/* 31 */ })(__cb(_, function() { | |
/* 31 */ return (function(_) { | |
var __4 = target; | |
if (__4) { | |
return _(null, __4); | |
} | |
/* 32 */ ; | |
return getTarget(__cb(_, function(__0, __6) { | |
var __5 = (target = __6); | |
return _(null, __5); | |
})); | |
/* 32 */ })(__cb(_, function() { | |
/* 32 */ return __break(); | |
})); | |
})); | |
case "follow": | |
return (function(_) { | |
var __5 = user; | |
if (__5) { | |
return _(null, __5); | |
/* 34 */ } | |
/* 34 */ ; | |
return getUser(__cb(_, function(__0, __7) { | |
/* 35 */ var __6 = (user = __7); | |
return _(null, __6); | |
})); | |
})(__cb(_, function() { | |
return (function(_) { | |
/* 35 */ var __6 = target; | |
/* 35 */ if (__6) { | |
return _(null, __6); | |
} | |
; | |
return getTarget(__cb(_, function(__0, __8) { | |
/* 36 */ var __7 = (target = __8); | |
return _(null, __7); | |
})); | |
})(__cb(_, function() { | |
return __break(); | |
/* 36 */ })); | |
/* 36 */ })); | |
default: | |
return __break(); | |
}; | |
})(function() { | |
return __break(); | |
}); | |
default: | |
return __break(); | |
}; | |
})(function() { | |
return _(null, console.log("END")); | |
}); | |
}; | |
return METHOD(_); | |
}).call(this, __trap); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# async simulation helper: | |
async = (_) -> | |
setTimeout _, 500 | |
# assume we're dealing with a status change event | |
type = 'event' | |
kind = 'statusChange' | |
# assume we initially have no user or target | |
user = null | |
target = null | |
getUser = (_) -> | |
console.log 'fetching user...' | |
async _ | |
console.log 'user fetched.' | |
return {} | |
getTarget = (_) -> | |
console.log 'fetching target...' | |
async _ | |
console.log 'target fetched.' | |
return {} | |
METHOD = (_) -> | |
console.log "BEGIN" | |
switch type | |
when 'comment' | |
user or= getUser _ | |
target or= getTarget _ | |
when 'event' | |
switch kind | |
when 'statusChange' | |
user or= getUser _ | |
target or= getTarget _ | |
when 'follow' | |
user or= getUser _ | |
target or= getTarget _ | |
console.log "END" | |
METHOD _ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var METHOD, async, getTarget, getUser, kind, target, type, user; | |
async = function(_) { | |
return setTimeout(_, 500); | |
}; | |
type = 'event'; | |
kind = 'statusChange'; | |
user = null; | |
target = null; | |
getUser = function(_) { | |
console.log('fetching user...'); | |
async(_); | |
console.log('user fetched.'); | |
return {}; | |
}; | |
getTarget = function(_) { | |
console.log('fetching target...'); | |
async(_); | |
console.log('target fetched.'); | |
return {}; | |
}; | |
METHOD = function(_) { | |
console.log("BEGIN"); | |
switch (type) { | |
case 'comment': | |
user || (user = getUser(_)); | |
target || (target = getTarget(_)); | |
break; | |
case 'event': | |
switch (kind) { | |
case 'statusChange': | |
user || (user = getUser(_)); | |
target || (target = getTarget(_)); | |
break; | |
case 'follow': | |
user || (user = getUser(_)); | |
target || (target = getTarget(_)); | |
} | |
} | |
return console.log("END"); | |
}; | |
METHOD(_); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BEGIN | |
fetching user... | |
END | |
user fetched. | |
fetching target... | |
target fetched. | |
END |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment