Refactored Serializer
This commit is contained in:
parent
01ea070961
commit
8646c1f6bc
4 changed files with 54 additions and 49 deletions
|
|
@ -17,6 +17,7 @@ import scala.collection.immutable.{Map, HashMap}
|
|||
* @author Viktor Klang
|
||||
*/
|
||||
trait Cluster {
|
||||
|
||||
/**
|
||||
* Specifies the cluster name
|
||||
*/
|
||||
|
|
@ -159,7 +160,7 @@ abstract class BasicClusterActor extends ClusterActor {
|
|||
|
||||
case RegisterLocalNode(s) => {
|
||||
log debug ("RegisterLocalNode: %s", s)
|
||||
local = Node(local.endpoints + s)
|
||||
local = Node(s :: local.endpoints)
|
||||
broadcast(Papers(local.endpoints))
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +243,7 @@ object Cluster extends Cluster with Logging {
|
|||
"Can't start cluster since the 'akka.remote.cluster.actor' configuration option is not defined")
|
||||
|
||||
val serializer = Class.forName(config.getString("akka.remote.cluster.serializer", DEFAULT_SERIALIZER_CLASS_NAME)).newInstance.asInstanceOf[Serializer]
|
||||
serializer setClassLoader loader
|
||||
serializer.classLoader = Some(loader)
|
||||
try {
|
||||
name map {
|
||||
fqn =>
|
||||
|
|
|
|||
|
|
@ -18,19 +18,17 @@ object RemoteProtocolBuilder {
|
|||
private var SERIALIZER_PROTOBUF: Serializer.Protobuf = Serializer.Protobuf
|
||||
|
||||
|
||||
def setClassLoader(classLoader: ClassLoader) = {
|
||||
SERIALIZER_JAVA = new Serializer.Java
|
||||
SERIALIZER_JAVA_JSON = new Serializer.JavaJSON
|
||||
SERIALIZER_SCALA_JSON = new Serializer.ScalaJSON
|
||||
SERIALIZER_JAVA.setClassLoader(classLoader)
|
||||
SERIALIZER_JAVA_JSON.setClassLoader(classLoader)
|
||||
SERIALIZER_SCALA_JSON.setClassLoader(classLoader)
|
||||
def setClassLoader(cl: ClassLoader) = {
|
||||
SERIALIZER_JAVA.classLoader = Some(cl)
|
||||
SERIALIZER_JAVA_JSON.classLoader = Some(cl)
|
||||
SERIALIZER_SCALA_JSON.classLoader = Some(cl)
|
||||
}
|
||||
|
||||
def getMessage(request: RemoteRequest): Any = {
|
||||
request.getProtocol match {
|
||||
case SerializationProtocol.SBINARY =>
|
||||
val renderer = Class.forName(new String(request.getMessageManifest.toByteArray)).newInstance.asInstanceOf[SBinary[_ <: AnyRef]]
|
||||
val renderer = Class.forName(
|
||||
new String(request.getMessageManifest.toByteArray)).newInstance.asInstanceOf[SBinary[_ <: AnyRef]]
|
||||
renderer.fromBytes(request.getMessage.toByteArray)
|
||||
case SerializationProtocol.SCALA_JSON =>
|
||||
val manifest = SERIALIZER_JAVA.in(request.getMessageManifest.toByteArray, None).asInstanceOf[String]
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ import sjson.json.{Serializer => SJSONSerializer}
|
|||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
trait Serializer {
|
||||
var classLoader: Option[ClassLoader] = None
|
||||
|
||||
def deepClone(obj: AnyRef): AnyRef
|
||||
|
||||
def out(obj: AnyRef): Array[Byte]
|
||||
|
||||
def in(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef
|
||||
|
||||
protected var classLoader: Option[ClassLoader] = None
|
||||
|
||||
def setClassLoader(cl: ClassLoader) = classLoader = Some(cl)
|
||||
}
|
||||
|
||||
// For Java API
|
||||
|
|
@ -55,7 +55,7 @@ object Serializer {
|
|||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object Java extends Java
|
||||
class Java extends Serializer {
|
||||
trait Java extends Serializer {
|
||||
def deepClone(obj: AnyRef): AnyRef = in(out(obj), None)
|
||||
|
||||
def out(obj: AnyRef): Array[Byte] = {
|
||||
|
|
@ -67,7 +67,8 @@ object Serializer {
|
|||
}
|
||||
|
||||
def in(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
|
||||
val in = if (classLoader.isDefined) new ClassLoaderObjectInputStream(classLoader.get, new ByteArrayInputStream(bytes))
|
||||
val in =
|
||||
if (classLoader.isDefined) new ClassLoaderObjectInputStream(classLoader.get, new ByteArrayInputStream(bytes))
|
||||
else new ObjectInputStream(new ByteArrayInputStream(bytes))
|
||||
val obj = in.readObject
|
||||
in.close
|
||||
|
|
@ -79,18 +80,21 @@ object Serializer {
|
|||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object Protobuf extends Protobuf
|
||||
class Protobuf extends Serializer {
|
||||
trait Protobuf extends Serializer {
|
||||
def deepClone(obj: AnyRef): AnyRef = in(out(obj), Some(obj.getClass))
|
||||
|
||||
def out(obj: AnyRef): Array[Byte] = {
|
||||
if (!obj.isInstanceOf[Message]) throw new IllegalArgumentException("Can't serialize a non-protobuf message using protobuf [" + obj + "]")
|
||||
if (!obj.isInstanceOf[Message]) throw new IllegalArgumentException(
|
||||
"Can't serialize a non-protobuf message using protobuf [" + obj + "]")
|
||||
obj.asInstanceOf[Message].toByteArray
|
||||
}
|
||||
|
||||
def in(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
|
||||
if (!clazz.isDefined) throw new IllegalArgumentException("Need a protobuf message class to be able to serialize bytes using protobuf")
|
||||
if (!clazz.isDefined) throw new IllegalArgumentException(
|
||||
"Need a protobuf message class to be able to serialize bytes using protobuf")
|
||||
// TODO: should we cache this method lookup?
|
||||
val message = clazz.get.getDeclaredMethod("getDefaultInstance", EMPTY_CLASS_ARRAY: _*).invoke(null, EMPTY_ANY_REF_ARRAY: _*).asInstanceOf[Message]
|
||||
val message = clazz.get.getDeclaredMethod(
|
||||
"getDefaultInstance", EMPTY_CLASS_ARRAY: _*).invoke(null, EMPTY_ANY_REF_ARRAY: _*).asInstanceOf[Message]
|
||||
message.toBuilder().mergeFrom(bytes).build
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +108,7 @@ object Serializer {
|
|||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object JavaJSON extends JavaJSON
|
||||
class JavaJSON extends Serializer {
|
||||
trait JavaJSON extends Serializer {
|
||||
private val mapper = new ObjectMapper
|
||||
|
||||
def deepClone(obj: AnyRef): AnyRef = in(out(obj), Some(obj.getClass))
|
||||
|
|
@ -118,8 +122,10 @@ object Serializer {
|
|||
}
|
||||
|
||||
def in(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
|
||||
if (!clazz.isDefined) throw new IllegalArgumentException("Can't deserialize JSON to instance if no class is provided")
|
||||
val in = if (classLoader.isDefined) new ClassLoaderObjectInputStream(classLoader.get, new ByteArrayInputStream(bytes))
|
||||
if (!clazz.isDefined) throw new IllegalArgumentException(
|
||||
"Can't deserialize JSON to instance if no class is provided")
|
||||
val in =
|
||||
if (classLoader.isDefined) new ClassLoaderObjectInputStream(classLoader.get, new ByteArrayInputStream(bytes))
|
||||
else new ObjectInputStream(new ByteArrayInputStream(bytes))
|
||||
val obj = mapper.readValue(in, clazz.get).asInstanceOf[AnyRef]
|
||||
in.close
|
||||
|
|
@ -136,7 +142,7 @@ object Serializer {
|
|||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object ScalaJSON extends ScalaJSON
|
||||
class ScalaJSON extends Serializer {
|
||||
trait ScalaJSON extends Serializer {
|
||||
def deepClone(obj: AnyRef): AnyRef = in(out(obj), None)
|
||||
|
||||
def out(obj: AnyRef): Array[Byte] = SJSONSerializer.SJSON.out(obj)
|
||||
|
|
@ -158,7 +164,7 @@ object Serializer {
|
|||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object SBinary extends SBinary
|
||||
class SBinary {
|
||||
trait SBinary {
|
||||
import sbinary.DefaultProtocol._
|
||||
|
||||
def deepClone[T <: AnyRef](obj: T)(implicit w : Writes[T], r : Reads[T]): T = in[T](out[T](obj), None)
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ trait PersistentRef[T] extends Transactional with Committable {
|
|||
trait PersistentQueue[A] extends scala.collection.mutable.Queue[A]
|
||||
with Transactional with Committable with Logging {
|
||||
|
||||
abstract case class QueueOp
|
||||
sealed trait QueueOp
|
||||
case object ENQ extends QueueOp
|
||||
case object DEQ extends QueueOp
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue