首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala PartialFunction堆栈溢出

Scala PartialFunction堆栈溢出
EN

Stack Overflow用户
提问于 2016-03-13 08:54:51
回答 1查看 275关注 0票数 2

我正在开发一个名为PySpark Cassandra的Scala / Python库。在它中,我必须处理对象、序列化的Python对象(例如,保存数据)。

我有一份工作因为重叠而失败:

代码语言:javascript
复制
org.apache.spark.SparkException: Job aborted due to stage failure: Task 250 in stage 2.0 failed 4 times, most recent failure: Lost task 250.3 in stage 2.0 (TID 411, sp-prod-adg02.priv.tgho.nl): java.lang.StackOverflowError
        at pyspark_cassandra.UnpickledUUIDConverter$$anonfun$convertPF$1.applyOrElse(Pickling.scala:121)
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:165)
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:166)
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:166)
        ...
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:166)
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:166)

启动此跟踪的代码是:

代码语言:javascript
复制
object UnpickledUUIDConverter extends TypeConverter[UUID] {
  val tt = typeTag[UUID]
  def targetTypeTag = tt
  def convertPF = { case holder: UUIDHolder => holder.uuid }
}

位于cassandra/Pickling.scala#L 118 (获取更多详细信息和上下文)。

UUIDHolder类定义为:

代码语言:javascript
复制
class UUIDHolder {
  var uuid: UUID = null

  def __setstate__(values: HashMap[String, Object]): UUID = {
    val i = values.get("int").asInstanceOf[BigInteger]
    val buffer = ByteBuffer.wrap(i.toByteArray())
    uuid = new UUID(buffer.getLong(), buffer.getLong())
    uuid
  }
}

(这个类的奇怪构造是为了与py4j兼容,以及UUID对象是如何被Python筛选的)

但是我对Scala的理解以及case块和PartialFunctions之间的关系是相当有限的。特别是我的案例块与https://github.com/scala/scala/blob/2.10.x/src/library/scala/PartialFunction.scala#L166的关系(我运行在Scala2.10.5上)

使我的处境更糟:)我很难始终如一地重复错误。它发生在不同节点上的星火作业中,而不是所有时间。保存该数据集时,我有一个存在问题的数据集。但我不能把它钉在数据集中的特定记录上。

在任何情况下,我都不会期望有此代码的StackOverflow。任何帮助都是非常感谢的!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-13 20:50:26

要回答简单的部分:

您的case块是一个部分函数文字,如解释的这里,也就是一个模式匹配的匿名函数。这是因为convertPF的返回类型是一个部分函数。

它得到一个描述为applyOrElse这里,它避免调用ifDefined,然后调用apply

堆栈上的OrElse正是包装pf1 orElse pf2的东西。它的applyOrElse实现委托给每个PartialFunction。

一个非常长的pfi orElse pfi_++链可能会在计算或orElse_i orElse (orElse_i++ orElse ...)上溢出堆栈。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35968360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档