A library that caches ZooKeeper data.
It is written in Scala and the cache synchronization is done using Akka.
The library caches data using a ZooKeeper instance, by specifying watches in the znode
s that should be cached.
The paths and the subtrees to cache are defined using the library's API.
- Built on top of the ZooKeeper API
- Cache the whole ZooKeeper tree, or just parts of it
- Data synchronization using Akka Actors
- Access with Scala, Akka, or Java messaging API
- Deployed in the Maven Central:
<dependency>
<groupId>com.github.astonbitecode</groupId>
<artifactId>scakka-zoo-cache</artifactId>
<version>0.1.0</version>
</dependency>
Assuming that zk is a ZooKeeper
class instance, a ScakkaZooCache
can be created like following:
####1. Using simple initialization
import com.github.astonbitecode.zoocache.ScakkaZooCacheFactory
val zooCache = ScakkaZooCacheFactory.scala(zk)
####2. Defining an ActorSystem
import com.github.astonbitecode.zoocache.ScakkaZooCacheFactory
val actorSystem = ActorSystem("myActorSystem")
val zooCache = ScakkaZooCacheFactory.scala(zk, actorSystem)
####3. Creating from inside an Akka Actor, using the ActorContext
import com.github.astonbitecode.zoocache.ScakkaZooCacheFactory
// This is one Actor
class MyActor extends Actor {
// Create a zoocache instance
val zooCache = ScakkaZooCacheFactory.scala(zk, context)
// Handle messages
override def receive(): Receive = {
case _ => ... // Use the zoo cache
}
}
Simply call the addPathToCache:
zooCache.addPathToCache("/cache/this/path")
val children = zooCache.getChildren("/a/path")
val data = zooCache.getData("/a/path")
import com.github.astonbitecode.zoocache.ScakkaZooCacheFactory
// Create your ActorSystem
val actorSystem = ActorSystem("myActorSystem")
// Create a ScakkaZooCache
val zooCache = ScakkaZooCacheFactory.scala(zk, actorSystem)
// Get the Akka Props from the factory
val props = ScakkaZooCacheFactory.props()
// Create the ActorRef
val zooCacheActorRef = actorSystem.actorOf(props)
// Contact the ActorRef
zooCacheActorRef ! GetChildren("/a/path")
zooCacheActorRef ! AddPathToCache("/a/path")
zooCacheActorRef ! GetChildren("/a/path")
zooCacheActorRef ! GetData("/a/path")
The available messages for the Akka API exist in the com.github.astonbitecode.zoocache.api.akka
package.
Each one of the available Akka messages has its corresponding response. This message is sent by the Actor that handles the Akka API as a response to a request. (You can consult the Scaladocs for more details).
For example, when sending a GetChildren
message, a response of GetChildrenResponse
will be received:
val askFuture = zooCacheActorRef ? GetChildren("/a/path")
val children: GetChildrenResponse = Await.result(askFuture, 30 seconds)
Akka users are not obliged to use the Ask pattern. All the Akka messages offered by the ScakkaZooCache API have an Optional parameter that can be used for Request-Response correlation:
import com.github.astonbitecode.zoocache.ScakkaZooCacheFactory
import com.github.astonbitecode.zoocache.api.akka._
// This is one Actor
class MyActor extends Actor {
// Create a zoocache instance
val zooCache = ScakkaZooCacheFactory.scala(zk, context)
// Create the zoocache Actor to handle the Akka API messages
val zooCacheActorRef = context.actorOf(ScakkaZooCacheFactory.props(zooCache))
// Send a message to the zooCacheActor
zooCacheActorRef ! GetChildren("/a/path", Some("123"))
// Handle the Responses
override def receive(): Receive = {
case getChildrenResponse: GetChildrenResponse => {
if (getChildrenResponse.correlation == Some("123")) {
println("OK")
} else {
println("CORRELATION ERROR")
}
}
case _ =>
}
}
In case of failure of any of the Akka API messages, the sender will receive a CacheFailure
.
This message contains the failure details along with any correlation object the respective request contained.