You can get to something very easy to use using the Shapeless library by Miles Sabin. See what they can do with a Tuple. Specifically abstracting over arity.
import syntax.std.tuple._
import poly._
var myProducedTuple = myTuple map (_(session))
Question
We have a trait that among other things contains an execute[T <: Record](Seq[(Session) => T]): Seq[T]
method, where Record
is the supertrait of all traits that we're retrieving from the database
trait DbTrait {
val threadCount: Int
val db: Database
protected def getGroupSize(size: Int, threadCount: Int) {
(size / threadCount) + if(size % threadCount == 0) 0 else 1
}
def execute[T <: Record](funs: Seq[(Session) => T]): Seq[T]
}
trait DbTraitSingle extends DbTrait {
val threadCount = 1
def execute[T <: Record](funs: Seq[(Session) => T]): Seq[T] =
db.withSession{session: Session => funs.map(f => f(session))}
}
trait DbTraitMulti extends DbTrait {
val threadCount = 4
def execute[T <: Record](funs: Seq[(Session) => T): Seq[T] =
funs.grouped(getGroupSize(funs.size, threadCount)).map(funs => Future {
db.withSession{session: Session => funs.map(f => f(session))}
}.toList.flatten
}
and so on. Ideally we'd like to be able to create something like a
def executePoly2[T1 <: Record, T2 <: Record]
(tuple: Tuple2[(Session) => T1, (Session) => T2]): Tuple2[T1, T2]
for arbitrary tuples (i.e. an executePoly3, executePoly4, etc), but there are two problems:
seq.grouped
method call, or are we stuck having special cases for all of the different threadCount
values (which at present doesn't exceed 4)?Solution
You can get to something very easy to use using the Shapeless library by Miles Sabin. See what they can do with a Tuple. Specifically abstracting over arity.
import syntax.std.tuple._
import poly._
var myProducedTuple = myTuple map (_(session))