change serialization to strictly rely on subtyping
- when encountering new message type, check all bindings which map apply - if multiple are found, choose the most specific one if that exists or verify that all mappings yield the same serializer - in case of remaining ambiguity, throw exception - also add special handling for “none” serializer mapping: turn off a default
This commit is contained in:
parent
50d107e150
commit
8b9f1caf67
6 changed files with 72 additions and 44 deletions
|
|
@ -125,17 +125,23 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
|
|||
def serializerFor(clazz: Class[_]): Serializer =
|
||||
serializerMap.get(clazz) match {
|
||||
case null ⇒
|
||||
val ser = bindings.collectFirst {
|
||||
case (c, s) if c.isAssignableFrom(clazz) ⇒ s
|
||||
} getOrElse (throw new NotSerializableException(
|
||||
"No configured serialization-bindings for class [%s]" format clazz.getName))
|
||||
// bindings are ordered from most specific to least specific
|
||||
def unique(cs: Seq[Class[_]], ser: Set[Serializer]): Boolean = (cs forall (_ isAssignableFrom cs(0))) || ser.size == 1
|
||||
|
||||
// memorize for performance
|
||||
serializerMap.putIfAbsent(clazz, ser) match {
|
||||
case null ⇒
|
||||
log.debug("Using serializer[{}] for message [{}]", ser.getClass.getName, clazz.getName)
|
||||
ser
|
||||
case some ⇒ some
|
||||
val possible = bindings filter { _._1 isAssignableFrom clazz }
|
||||
possible.size match {
|
||||
case 0 ⇒
|
||||
throw new NotSerializableException("No configured serialization-bindings for class [%s]" format clazz.getName)
|
||||
case x if x == 1 || unique(possible map (_._1), possible.map(_._2)(scala.collection.breakOut)) ⇒
|
||||
val ser = possible(0)._2
|
||||
serializerMap.putIfAbsent(clazz, ser) match {
|
||||
case null ⇒
|
||||
log.debug("Using serializer[{}] for message [{}]", ser.getClass.getName, clazz.getName)
|
||||
ser
|
||||
case some ⇒ some
|
||||
}
|
||||
case _ ⇒
|
||||
throw new NotSerializableException("Multiple serializers found for " + clazz + ": " + possible)
|
||||
}
|
||||
case ser ⇒ ser
|
||||
}
|
||||
|
|
@ -160,7 +166,7 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
|
|||
* It is primarily ordered by the most specific classes first, and secondly in the configured order.
|
||||
*/
|
||||
private[akka] val bindings: Seq[ClassSerializer] = {
|
||||
val configuredBindings = for ((k: String, v: String) ← settings.SerializationBindings) yield {
|
||||
val configuredBindings = for ((k: String, v: String) ← settings.SerializationBindings if v != "none") yield {
|
||||
val c = ReflectiveAccess.getClassFor(k, system.internalClassLoader).fold(throw _, identity[Class[_]])
|
||||
(c, serializers(v))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue