I am currently trying to traverse a graph representing a set of software components.
Some of them are implementing a "Start" interface so that they can be started (think database connection, actor system, JMX registration,...):
trait Start {
// start a given component
def start: Eval[StartResult]
}
sealed trait StartResult
case class StartOk(message: String) extends StartResult
case class StartFailure(message: String) extends StartResult
case class StartError(message: String, exception: Throwable) extends StartResult
I have implemented the following strategy to start the components in order (starting from the bottom):
/** start components from the bottom up */
def start[G](graph: G): Eval[List[StartResult]] = Eval.later {
val results: ListBuffer[StartResult] = new ListBuffer[StartResult]
val startStrategy =
somebu(strategy[Any] {
case s: Start =>
s.start.value match {
case s: StartOk => results.append(s); None
case other => results.append(other); Option(s)
}
})
rewrite(startStrategy)(graph)
results.toList
}
This strategy is using an external mutable variable to collect the start results.
I have the impression that I should be using something like "collect" for this kind of traversal but collect does a top down traversal and wouldn't stop collecting on a failure.
Is there another way to do a "collect" and parameterize it with a given strategy?
Thanks.
Eric.