我试图将表查询对象从本地actor发送到远程actor, 但是akka给出了序列化异常
远程Actor看起来像这样,我在这里使用活跃的光滑模式
object RemoteActor {
case class Entry[M, I: BaseColumnType, T <: IdTable[M, I]](tableWithIdQuery: TableWithIdQuery[M, I, T], model: M)
}
class RemoteActor extends Actor with ActorLogging {
import RemoteActor._
lazy val db = Database.forURL(
url = "jdbc:mysql://localhost/demo",
driver = "com.mysql.jdbc.Driver",
user= "root",
password= "root")
override def receive = {
case Entry(table, model) =>
//I will wrap this code in a Future and use akka.pattern.pipe
// thus avoiding deafening the actor
//avoided wrapping in future just to avoid clutter
db.withSession { implicit sx =>
table.createIfNotExists
table.save(model)
}
log.info("done saving to database")
case msg => log.info(s"unknown message of type ${msg.getClass}")
}
}
本地演员看起来像这样。 Local Actor构建TableWithIdQuery并将其传递给上面提到的Remote Actor。
class LocalActor extends Actor with ActorLogging {
import LocalActor._
var remoteActor: Option[ActorSelection] = None
override def preStart(): Unit = {
remoteActor = Some(context.actorSelection("akka.tcp://ActorSystem@127.0.0.1:2222/user/RemoteActor"))
remoteActor.getOrElse {
println(" unreachable, shutting down :(")
context.stop(self)
}
}
override def receive = {
case Send =>
case class User(name: String, id: Option[Long] = None)
class Users(tag: Tag) extends IdTable[User, Long](tag, "users") {
def name = column[String]("name")
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def * = (name, id.?) <> (User.tupled, User.unapply)
}
val users = new TableWithIdQuery[User, Long, Users](tag => new Users(tag)) {
override def extractId(model: User): Option[Long] = model.id
override def withId(model: User, id: Long): User = model.copy(id = Some(id))
}
import remote.RemoteActor._
remoteActor.map(remote => remote ! Entry[User, Long, Users](users, User("pamu nagarjuna")))
log.info("message sent :)")
case msg => log.info(s"unknown message of type ${msg.getClass}")
}
}
答案 0 :(得分:2)
假设像Query这样的东西是可序列化的,这是不安全的。您真的应该在本地上下文中运行查询,将结果映射到一组可序列化类型(例如,不可变集合,案例类),然后发送它。