Ophirr Ophirr - 2 months ago 8
Scala Question

Scala OnCreate alternative implementation

I was waiting for 2.12 to be able to use the onCreate hook, but it seems that it's been pushed off until 2.13. Are there any suggestions for a way to make a decent alternative? In essence, I have a trait and an abstract class as follows:

trait Issue {
def details: ...
def logic: ...
def toSimpleView: ...
}

abstract class AbstractIssue extends(source: IssueSource) extends Issue{
val extraDetail: ...
}


There exist multiple different implementations of the
AbstractIssue
, and on the initialization of an issue I want to grab it and put a simplified representation of it into a database, then return it to the code as usual. The goal is to only put it into the database after all the fields in the child class have been initialized, and also to only have to write this code in the
AbstractIssue
and
Issue
to avoid hunting down every existing child
Issue
.

My gut reaction to this problem is to add this to the abstract constructor:

abstract class AbstractIssue extends(source: IssueSource) extends Issue{
val extraDetail: ...
Future { Thread.sleep(2000) }.foreach(_ => InsertIssue(this.toSimpleView)) }
}


Unfortunately, that's a terrible way to do it, and I'm struggling to come up with a clean solution. Does anyone have any ideas?

Answer

What I ended up doing as a hack until onCreate comes out:

def hackToHandleAfterInitialization(handler:IssueHandler):Future[Unit] = {
import scala.concurrent.blocking
Future {
  var continue = true
  while (continue) {
    try {
      blocking(synchronized(handler.handleProblem(this)))
      continue = false
    } catch {
      case un:UninitializedFieldError =>
        Thread.sleep(5)
        continue = true
    }
  }
  Unit
}

And then in the abstract class:

abstract class AbstractIssue extends(source: IssueSource) extends Issue{
    val extraDetail: ...
    hackTohandleAfterInitialization(DefaultHandler())
}