Created
July 23, 2013 11:26
-
-
Save rkuhn/6061663 to your computer and use it in GitHub Desktop.
“unbecoming” blog post races
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 isDownloading = false | |
// set up a scheduler to sync the registry | |
system.scheduler.schedule(0 millis, 3 hours) { | |
if(!isDownloading) { | |
system.actorOf(Props[Downloader]) ! Download | |
} | |
} | |
/* | |
* Since isDownloading is not volatile any write performed by another thread | |
* might not ever be visible to the code above, in principle it would be | |
* a correct implementation to always execute the conditional branch. | |
*/ |
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
class Downloader extends Actor { | |
import context._ | |
def receive = { | |
case _ => | |
download onComplete unbecome | |
/* | |
* The line above is really problematic, since you are calling | |
* context.unbecome from a different thread; ActorContext must | |
* not ever leave the actor, and you are throwing it out there. | |
* The resulting race condition is that either the become or the | |
* unbecome can be lost when they happen “at the same time”. | |
*/ | |
become { | |
case _ => // do nothing | |
} | |
} | |
def download = future { | |
// perform download | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment