Skip to content

Instantly share code, notes, and snippets.

@mpkocher
Last active October 2, 2019 15:24
Show Gist options
  • Save mpkocher/fdad5a74f04b71bb245c to your computer and use it in GitHub Desktop.
Save mpkocher/fdad5a74f04b71bb245c to your computer and use it in GitHub Desktop.
Scala's Cake Patten Example
// This is all write by hand and probably has typos.
// The general idea is to show how it composes and how other
// system that extend the core services can choose which implementations
// of the coreservice DAOs to use
trait CoreServiceDaos {
val logDao: LogDao
val healthDao: HealthDao
}
trait BaseCoreActors {
this: Core with CoreServiceDaos =>
lazy val statusActor = system.actorOf(Props[StatusServiceActor])
lazy val healthActor = system.actorOf(Props(new HealthActor(healthDao), "health-actor"))
lazy val logActor = system.actorOf(Props(new LogActor(logDao), "log-actor")
}
trait BaseServiceRoutes extends RouteConcatenation{
this: BaseCoreActors with Core with CoreServiceDaos =>
//
val logDao = new InMemoryDao
// val logDao = new LogSqlDao(dbconfig)
val gauges = Seq(HealthGauge("my-gauge", "name", "Desc"))
val healthDao = new HealthDao(gauges)
// Create my Services
val baseServices = Seq(
new StatusService(statusActor),
new SubSystemResourceService(),
new SubSystemConfigService(),
new SubSystemComponentService(),
new LogService(logActor),
new HealthService(healthActor))
}
trait Api extends RouteConcatenation with BaseServiceRoutes{
this: BaseCoreActors with Core with CoreServiceDaos =>
private implicit val _ = system.dispatcher
val manifestService = new ManifestService(baseServices.map(x => x.manifest))
def mergeRoutes(a: Route, b: Route): Route = {
a ~ b
}
val routes = baseServices.map(i => i.routes).fold(manifestService.routes)(mergeRoutes)
val rootService = system.actorOf(Props(new RoutedHttpService(routes)))
}
trait SecondaryAnalysisApi extends BaseServiceRoutes {
this: SecondaryCoreActors with Core with CoreServiceDaos with EngineSystemConfig with PipelineTemplateConfig =>
private implicit val _ = system.dispatcher
// I can still decide which implementation of the core service Actor Daos here.
val logDao = new InMemoryDao
// val logDao = new LogSqlDao(dbconfig)
val gauges = Seq(HealthGauge("my-gauge", "name", "Desc"),
HealthGauge("my-extended-system-gauge", "name", "Desc"))
val healthDao = new HealthDao(gauges)
// pull in base services without changing anything
val subSystemServices = baseServices ++ Seq(
new SecondaryAnalysisServiceStatus(),
new JobManagerService(dbActor, engineManagerActor, engineConfig),
new JobEngineService(engineManagerActor, engineDaoActor, engineConfig),
new DataSetService(dbActor),
new PipelineTemplateService(pipelineTemplateActor),
new DataSetImportService(dbActor))
lazy val manifestService = new ManifestService(subSystemServices.map(x => x.manifest))
def mergeRoutes(a: Route, b: Route): Route = {
a ~ b
}
val routes = subSystemServices.map(i => i.routes).fold(manifestService.routes)(mergeRoutes)
// For backward compatibility in the tests
val totalRoutes = routes
val rootService = system.actorOf(Props(new RoutedHttpService(routes)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment