For make faster compile go...less traits having?

280 views Asked by At

EDIT
Complicating matters it appears that there is an issue (that is being worked on in Play 2.1 snapshot) where routes file change can also trigger the stampeding herd effect, which is to say, recompiling controllers and dependencies. Once that is resolved, and Scala 2.10 + SBT 0.12.1 performance enhancements are integrated, then it will become more clear how much I am shooting myself in the foot with trait-based DAO repository...

ORIGINAL
I am of the English speak many, many capable, don't worry, just drawing you in....to the dreaded slow a$$ compilation zone

trait DaoProviderContract {
  def team:   TeamContract
  def player: PlayerContract
}
object DaoRepo extends DaoProviderContract {
  import com.company.utils.{Connection, Driver}
  implicit lazy val db = Connection.getHandle(Driver.DEFAULT)

  val team    = new TeamDAO
  val player  = new PlayerDAO
}
trait DaoProvider[Contract <: com.company.dao.DAOContract[_]] {
  val daoRepo = DaoRepo
  val dao: Contract
}
trait TeamData extends DaoProvider[TeamContract] {
  val dao: TeamContract = daoRepo.team
}
trait PlayerData extends DaoProvider[PlayerContract] {
  val dao: PlayerContract = daoRepo.player
}

and then in a controller, mixin a DAO component:

object Player extends Controller with PlayerData {
  ....
}

making a change to the above controller seems to be triggering the recompilation of all sources that depend on the DAO provider, which in my case is a bunch of controllers. The net affect is that often I'm seeing nearly 3/4 of my application recompiled, annoying.

Now, SBT 0.12.1 has improved in terms of compilation speed, but in terms of what it recompiles, my DAO repository implementation is clearly not helping matters.

So, my question is, in this case should I just scrap the traits and expose the DaoRepo object directly to controllers? The Player controller would then look something like:

import model.{DaoRepo => repo}
object Player extends Controller { // with PlayerData mixin gone
  def player(id: Int) = repo.player.get(id)
}

Am I correct in the assumption that making a change to the modified Player controller will NOT trigger the recompilation of 3/4 of my application? Impossible to test using the DaoRepo object directly, I know, but then waiting around is not terribly productive either.

Thanks for feedback if you've got it re: helping SBT recompile the necessary...

1

There are 1 answers

3
paradigmatic On BEST ANSWER

You can make SBT incremental process smarter by avoiding stuffing a single file with several traits/class/object definitions. If you have a file with:

trait A { }
trait B extends Base { }

Changing the definition of Base will trigger a recompilation of the file, which will in turn trigger the recompilation of every file where A or B are referred...

Try to split DAO and PlayerData class in several files.