【发布时间】:2018-05-28 03:33:45
【问题描述】:
我正在研究 akka-persistence,并遇到了对象序列化的典型问题。我的对象(如下所示)具有基本类型和功能。我读过this、this 和this,但没有一个帮助我使以下序列化。
测试工具
object SerializationUtil {
def write(obj: Any): String = {
val temp = Files.createTempFile(null, null).toFile
val out = new ObjectOutputStream(new FileOutputStream(temp))
out.writeObject(obj)
out.close()
temp.deleteOnExit()
temp.getAbsolutePath
}
def read[T](file: String) = {
val in = new ObjectInputStream(new FileInputStream(new File(file)))
val obj = in.readObject().asInstanceOf[T]
in.close()
obj
}
}
统计数据
case class Stats(
app: String,
unit: ChronoUnit,
private var _startupDurations: List[Long]
) {
def startupDurations = _startupDurations.sorted
def startupDurations_=(durations: List[Long]) = _startupDurations = durations
@transient lazy val summary: LongSummaryStatistics = {
_startupDurations.asJava.stream()
.collect(summarizingLong(identity[Long]))
}
}
Stats 序列化就好了。
"SerializationUtil" should "(de)serialize Stats" in {
val file = SerializationUtil.write(newStats())
val state = SerializationUtil.read[Stats](file)
verifyStats(state)
}
但这不是:case class GetStatsForOneRequest(app: String, callback: Stats => Unit)
java.io.NotSerializableException: org.scalatest.Assertions$AssertionsHelper
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
也试过了:
trait SerializableRunnable[T] extends scala.Serializable with ((T) => Unit)
将回调实现为SerializableRunnable 的实例,但没有运气。
想法?
编辑:
也许我应该澄清遇到此问题的实际用例以提供更多上下文。该函数是来自 Akka HTTP route 的回调,如下所示:
path("stats") {
logRequest("/stats") {
completeWith(instanceOf[List[Stats]]) { callback =>
requestHandler ! GetStatsRequest(callback)
}
}
}
handler actor 会保持请求,直到它得到响应。构建最终输出可能需要多个响应。
我做了一些挖掘,似乎回调实现是CallbackRunnable。
【问题讨论】:
-
传递GetStatsForOneRequest时newStats()的实现是什么?它似乎适用于 GetStatsForOneRequest("app", _ => Unit)。
-
@igorpcholkin 只是一个带有虚拟值的
Stats。问题是回调函数 -
我真正想看到的是你如何构造在 SerializationUtil.write 调用中使用的 GetStatsForOneRequest(包括回调)。
标签: java scala serialization akka-persistence