处理使用诸如circe,enumeratum和shapeless之类的库的scala项目

我们定义了几个枚举,即Region; EntityType和EntityAction例如

sealed trait EntityAction extends EnumEntry with Hyphencase

case object EntityAction extends Enum[EntityAction] with CirceEnum[EntityAction] {
  //noinspection ScalaStyle
  case object * extends EntityAction

  case object CreateUser extends EntityAction
  ... omitted ...
}

我们还有一个Permission模型定义为

case class Permission(
                   resource: EntityType,
                   regions: Set[Region],
                   actions: Set[EntityAction],
                   instances: Set[String]
                 )

我们还有一个UserEntityModel(以json格式保存在我们的数据存储中)和一个UserModel,它是http响应的一部分返回

case class UserEntityV1(
                     override val entityKey: EntityKey,
                     firstName: String,
                     lastName: String,
                     override val email: String,
                     override val permissions: Set[Permission],
                     override val revokedPermissions: Set[Permission],
                     override val status: EntityStatus
                     ...

           ) extends UserEntity

EntityKey包含Region枚举,省略的字段为非枚举类型

case class User(
             override val uuid: Option[String] = None,
             firstName: String,
             lastName: String,
             email: String,
             status: EntityStatus,
             permissions: Set[Permission],
             revokedPermissions: Set[Permission]
             ...
           ) extends HasPayload

如果没有UserEntity和User模型的权限和revokedPermissions,则clean compile时间不到3分钟。 包含这些字段后,编译器会运行到

java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.Arrays.copyOfRange(Arrays.java:3664)
    at java.lang.String.<init>(String.java:201)
    at java.lang.StringBuilder.toString(StringBuilder.java:407)
    at scala.tools.nsc.transform.Erasure.fullNameInSig$1(Erasure.scala:261)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:292)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:359)

我们通过定义一个.sbtopts来解决它,并对其进行了一些修改,因为目前的.sbtopts是

-J-Xms1024M
-J-Xmx4G
-J-XX:ReservedCodeCacheSize=256M
-J-XX:MaxMetaspaceSize=1024M
-J-Xss2M

在使用diff Xss值以及指定-mem的情况下,似乎并没有太多差异。

但是,包括这些字段后,平均clean compile时间现在将近7分钟(因为在少数地方使用了用户实体)

所有指示均指向宏编译。 我们正在使用自动推导。 有没有一种方法可以使样例自由,并保持枚举的类型安全,但可以减少编译时间。

当前版本是

scala version =  2.12.1
sbt version = 0.13.13 
circeVersion = "0.7.0"
enumeratumVersion = "1.5.10"
enumeratumCirceVersion = "1.5.10"
shapelessVersion = "2.3.2"

在更新到最新版本的库和scala 2.12.3时,编译时间跳到将近20分钟

尝试从调试缓慢的编译时间开始执行一些步骤

据我所知,它保持打字阶段

  ask by Omar A translate from so

本文未有回复,本站智能推荐:

2回复

Scala-Circe-没有类名的案例类序列化

我以前曾使用Circe进行案例类序列化/反序列化,并且喜欢如何在没有其他Scala JSON库所需的样板代码的情况下使用Circe ,但是现在遇到了一个问题,我不确定如何解决。 我有一个ADT(带有几个case类实例的密封特征),我想(从我的Akka Http Service使用akka-ht
2回复

Scala宏和单独的编译单元

将来会克服这一限制吗? 还是有一些我不知道的解决方法? 现在,我有一个项目,我想在其中使用宏,但是它们需要依赖于该项目的特定类型。 为宏有一个单独的编译单元将需要我引入另一个以容纳通用类型,我不愿意在每次编写宏时都这样做。
1回复

如何在编译时检查String中的SQL,语言语法(Scala)

我正在写一个将DSL转换为多种编程语言的转换器(看起来像Apache Thrift )。 例如, 还应该将其翻译为Objective-C和JavaScript。 要实现它,我必须替换字符串 替换String中的代码片段类型不安全且令人沮丧,因为即使有错误,它也不会提供任何信息。
1回复

关闭方法的编译时结构类型

我的项目中有以下辅助方法: 我有一些具有close方法但未实现Closeable的类。 如果将辅助方法更改为使用结构类型,则仍可以在以下类上使用它: 但是,这引入了反射的使用,这是我在运行时要避免的事情。 有没有一种方法可以使用类似于结构化类型的东西而不会引起运行时反射? 即以
1回复

在宏中评估类型shapeless.Witness.Aux[T]的表达式失败

我试图在宏中评估shapeless.Witness.Aux[T]类型的隐式参数,以便使用单例类型T的值。这是一个最小的示例: 但是编译这个 失败并显示以下错误: println(show(typechecked))的输出是: println(show(untypechecked)
1回复

如何使用Shapeless或Macro将Scala案例类字段和值作为(字符串,字符串)获取

几天来,我一直在努力尝试创建一个宏或使用 shapeless 创建一个方法/函数来提取字段名称和值作为元组 [String, String]。 让我们想象以下案例类:case class Person(name: String, age: Int) 我想要这样的东西(在案例类中并不需要真正成为一种方
1回复

Scala宏注释不会扩展(宏天堂)

我正在尝试在项目中包含宏注释。 根据文档 ,我尝试实现它们的示例。 我知道宏模块必须在核心模块之前编译(核心是包含利用宏注释的代码的模块)。 为此,我创建了以下build.sbt(版本1.2.8): 我的项目的结构如下: 但是,当我在Test类中使用@identity批注时,仍然
3回复

将宏计算结果传递给运行时的推荐方法是什么?

我正在尝试构建一些类似SQL的抽象,我遇到了一个问题。 这是一个简化的“数据库表”: 这是我的查询抽象: 这是我的宏实现: 这是我的示例代码: 它编译并运行正常,但输出是: 基本上, result似乎是空的。 我预计它会保留树木的累积字符串。 如何将数据从宏编译阶段