Created
October 2, 2012 03:05
-
-
Save dyross/3815934 to your computer and use it in GitHub Desktop.
Scaling the Klout API with Scala, Akka, and Play
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
def blockingAndVerbose: Profile = { | |
val futureName = name() | |
val futureScore = score() | |
val futureFriends = Friends() | |
val nameResult = Await.result(futureName, 10 seconds) | |
val scoreResult = Await.result(futureScore, 10 seconds) | |
val friendsResult = Await.result(futureFriends, 10 seconds) | |
Profile(nameResult, scoreResult, friendsResult) | |
} |
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
def nonBlockingComposition: Future[Profile] = { | |
// NOTE: We declare these up here so they start in parallel. This is required | |
// because of how for expressions get expanded to maps and flatMaps. | |
val futureName = name() | |
val futureScore = score() | |
val futureFriends = friends() | |
for { | |
nameResult <- futureName | |
scoreResult <- futureScore | |
friendsResult <- futureFriends | |
} yield { | |
Profile(nameResult, scoreResult, friendsResult) | |
} | |
} |
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
def name(): Future[String] = Future { "david" } | |
def score(): Future[Double] = Future { 50.0 } | |
def friends(): Future[List[Int]] = Future { List(1, 2, 3) } |
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
case class Profile(name: String, score: Double, friends: List[Int]) |
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 MySQLStateService(private var nodes: Set[String]) { | |
def getHealthyNodes(): Set[String] = nodes | |
def updateState(node: String, status: Boolean) { | |
if (status) nodes = nodes + node | |
else nodes = nodes - node | |
} | |
} | |
val state: MySQLStateService = { | |
val service = new MySQLStateService(Set.empty) | |
Zoo.on("/Health/MySQL/node1") { | |
case NodeUpdated(value) if value == "UP" => state.updateState("node1", true) | |
case _ => state.updateState("node1", false) | |
} | |
service | |
} |
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 MySQLStateService(private val agent: Agent[Set[String]]) { | |
def getHealthyNodes(): Set[String] = agent.apply() | |
} | |
val service = { | |
val agent: Agent[Set[String]] = Agent(Set.empty) | |
Zoo.on("/Health/MySQL/node1") { | |
case NodeUpdated(value) if value == "UP" => agent send (prev => prev + "node1") | |
case _ => agent send (prev => prev - "node1") | |
} | |
new MySQLStateService(agent) | |
} |
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
import com.twitter.zookeeper.ZooKeeperClient | |
object Zoo { | |
lazy val zk: ZooKeeperClient = ... | |
def on(path: String)(callback: NodeStatusChange => Unit) = { | |
zk watchNode (path, { | |
(data: Option[Array[Byte]]) => | |
data match { | |
case Some(d) if d.isEmpty => | |
callback(NodeUpdated(None)) | |
case Some(d) => | |
val value = new String(d) | |
callback(NodeUpdated(Option(value))) | |
case None => | |
callback(NodeDeleted) | |
} | |
}) | |
} | |
} |
Some.apply(x) does the same thing as Option.apply(x) but has a more restrictive type.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
zk.scala, line 15, did you mean
callback(NodeUpdated(Some(value)))
?