2

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...

virtualeyes
  • 11,147
  • 6
  • 56
  • 91

1 Answers1

2

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.

paradigmatic
  • 40,153
  • 18
  • 88
  • 147
  • +1, yes, I am breaking rule #1: split classes into separate source files; however, looking under the hood in various scala libraries/applications I do see that this convention is often broken, likely because it's often easier to group some common functionality in a single source file. – virtualeyes Oct 16 '12 at 14:27
  • should note that I may be getting bitten by a "bug" in Play 2 framework where sometimes the routes file can be a culprit in the 3/4 app recompilation, something that is apparently being worked on with 2.1 snapshot – virtualeyes Oct 16 '12 at 14:29
  • @virtualeyes I don't consider it as a "rule". Just a trick to help the incremental compiler... – paradigmatic Oct 16 '12 at 15:03