Where does Boot.scala fit in? - scala

From time to time I see projects that has a boot.scala or Boot.scala file in. Though this does not appear to be a hard and fast Scala rule, it does appear to be folklore of sorts to include a Boot.scala file in some projects. This specific project uses Akka and Spray, which translates to actor pattern and REST services.
Will someone please explain what type of functionality can normally be expected in such a file and if this is a common pattern of sorts?
As an extension to this question (please answer the first bit first :-), I would be grateful to know how to read this code, which is in a project with multiple Boot.scala files.
Boot.scala in web package:
trait Web {
this: Api with Core =>
....
}
Boot.scala in api package:
trait Api {
this: Core =>
....
}
Boot.scala in core package:
trait Core {
implicit def actorSystem: ActorSystem
implicit val timeout = Timeout(30000)
val application = actorSystem.actorOf(
props = Props[ApplicationActor],
name = "application"
)
Await.ready(application ? Start(), timeout.duration)
}
One can gather that the one package depends on the other, and that the Boot.scala files may be a common sight in actor based systems, but what how does one 'read' the relationships? For example, how would I read trait Web {this: Api with Core =>...} in english?
In the particular instance, the starting point of the application lies in a main file:
object Main extends App {
implicit val system = ActorSystem("RESTService")
class Application(val actorSystem: ActorSystem) extends Core with Api with Web {
}
new Application(system)
sys.addShutdownHook {
system.shutdown()
}
}
I realize my questions may seem trivial to some, but I'm trying to get into the Scala tribe here, and the 'secret password' is not in any manual.

I don't know whether Boot.scala is a common pattern, but it is used in Lift and contains the main configuration of the application. Since Lift is rather old (relative to other scala projects) it might have set a convention.
For the other question you should read up on the cake pattern and self types. For example
trait Web {
this: Api with Core =>
....
}
defines a trait Web that can only be mixed into classes or traits that inherit from API and Core or have those as part of their self types. Thus
class Application(val actorSystem: ActorSystem) extends Core with Api with Web {
}
would not type check, if the Api trait wasn't mixed in, because it is required by the Web trait.

Related

Is there a way to "trickle down" implicits from top level applications to other imported modules?

I am trying to refactor some code for a program which uses an ActorSystem as the backbone for Http calls.
My specific goal is to make my code more modular so I can write libraries of functions which make http calls using an ActorSystem where the ActorSystem is later expected to be provided by the application.
This is a general question though as I tend to run into this problem a reasonable amount.
I have two goals:
Minimize the number of ActorSystems I create to simplify tracking of them (one per top level application is the goal)
Avoid explicitly passing around the ActorSystem and context everywhere it's needed.
Conceptually - the code below illustrates how I'm thinking about it (of course this code would not compile).
import akka.actor.ActorSystem
import intermediateModule._
import scala.concurrent.ExecutionContextExecutor
object MyApp extends App {
// Create the actorsystem and place into scope
implicit val system = ActorSystem()
implicit val context = system.dispatcher
intermediateFunc1(300)
}
// Elsewhere in the intermediate module
object intermediateModule {
import expectsActorSystemModule._
def intermediateFunc1(x: Int) = {
// Relies on ActorSystem and Execution context,
// but won't compile because, of course the application ActorSystem and
// ec is not in scope
usesActorSystem(x)
}
}
// In this modiule, usesActorSystem needs an ActorSystem
object expectsActorSystemModule {
def usesActorSystem(x: Int)
(implicit system: ActorSystem, context: ExecutionContextExecutor) = ???
//... does some stuff like sending http requests with ActorSystem
}
Is there a way to "trickle down" implicits through the sub-modules to achieve the goal of the top level application providing the needed implicits?
Can this be done in a way such that the "depth" of module imports doesn't matter (e.g. if I added a few more intermediate libraries in between the top level app and the module which requires the ActorSystem)?
The answer here is dependency injection. Every object that has dependencies on other objects should receive them as constructor parameters. The important thing here is that higher layers only get their own dependencies, and not their dependencies' dependencies.
In your example, IntermediateModule doesn't use the ActorSystem itself; it only needs it to pass it on to ExpectsActorSystemModule. This is bad, because if the latter changes and requires another dependency, you will need to change the former as well – that is too much coupling. You can refactor it like so:
import akka.actor.ActorSystem
import scala.concurrent.ExecutionContextExecutor
object MyApp extends App {
// Create the actorsystem and place into scope
// wire everything together
implicit val system = ActorSystem()
implicit val context = system.dispatcher
val expectsActorSystemModule = new ExpectsActorSystemModule
val intermediateModule = new IntermediateModule(expectsActorSystemModule)
// run stuff
intermediateModule.intermediateFunc1(300)
}
// Elsewhere in the intermediate module
class IntermediateModule(expectsActorSystemModule: ExpectsActorSystemModule) {
def intermediateFunc1(x: Int) = {
// Note: no ActorSystem or ExecutionContext is needed, because they were
// injected into expectsActorSystemModule
expectsActorSystemModule.usesActorSystem(x)
}
}
// In this module, usesActorSystem needs an ActorSystem
class ExpectsActorSystemModule(
implicit system: ActorSystem,
context: ExecutionContextExecutor) {
def usesActorSystem(x: Int) = ???
//... does some stuff like sending http requests with ActorSystem
}
Note that IntermediateModule no longer needs an ActorSystem or an ExecutionContext, because those were provided directly to ExpectsActorSystemModule.
The slightly annoying part is that at some point you have to instantiate all these objects in your application and wire them all together. In the above example it's only 4 lines in MyApp, but it will get significantly longer for more substantial programs.
There are libraries like MacWire or Guice to help with this, but I would recommend against using them. They make it much less transparent what is going on, and they don't save all that much code either – in my opinion, it's a bad tradeoff. And these two specifically have more downsides. Guice comes from the Java world and gives you basically no compile-time guarantees, meaning that your code might compile just fine and then fail to start because Guice. MacWire is better in that regard (everything is done at compile time), but it's not future-proof because it's implemented as a Scala 2 macro – it will not work on Scala 3 in its current form.
Another approach that is popular among the purely functional programming community is to use ZIO's ZLayer. But since you're working on an existing codebase that is based on the Lightbend tech stack, this is unlikely to be the means of choice in this particular case.

How to properly pass many dependencies (external APIs) to a class in Scala?

How to properly pass many dependencies (external APIs) to a class in Scala?
I'm working on the application that uses many APIs to collect data. For API's I have trait like below.
trait api {
def url: Foo
def parse: Bar
}
Also, there are about 10 implementations of the api trait (one for each API). Inside a parent actor, I want to create a child actor for every external API. I created new trait and implementation,
trait ExternalApis {
val apiList: List[api]
}
object MyApis extends ExternalApis {
val apiList = List(new ApiImpl1, ..., new ApiImpl10)
}
so now I can pass MyApis object (or any other implementation of ExternalApis) to parent actor and map over apiList for creating such child actors.
It seems to me I'm missing something. Are there more proper ways to do it?
The implementation that you have made looks nearly ready. Just something I would like to add are:
Passing an API List may not be the most ideal way to do such a thing. Anytime you would like to add/remove something to the API list, you would have to change different areas of the code. A suggestion would be to read this from a config folder, where the config folders would contain things such as url, username, password etc.
If you could provide more insight on the usage of these API's, it would help my answer a lot.
Hope this helped!

How do I specify type parameters via a configuration file?

I am building a market simulator using Scala/Akka/Play. I have an Akka actor with two children. The children need to have specific types which I would like to specify as parameters.
Suppose that I have the following class definition...
case class SecuritiesMarket[A <: AuctionMechanismLike, C <: ClearingMechanismLike](instrument: Security) extends Actor
with ActorLogging {
val auctionMechanism: ActorRef = context.actorOf(Props[A], "auction-mechanism")
val clearingMechanism: ActorRef = context.actorOf(Props[C], "clearing-mechanism")
def receive: Receive = {
case order: OrderLike => auctionMechanism forward order
case fill: FillLike => clearingMechanism forward fill
}
}
Instances of this class can be created as follows...
val stockMarket = SecuritiesMarket[DoubleAuctionMechanism, CCPClearingMechanism](Security("GOOG"))
val derivativesMarket = SecuritiesMarket[BatchAuctionMechanism, BilateralClearingMechanism](Security("SomeDerivative"))
There are many possible combinations of auction mechanism types and clearing mechanism types that I might use when creating SecuritiesMarket instance for a particular model/simulation.
Can I specify the type parameters that I wish to use in a given simulation in the application.conf file?
I see two questions here.
Can I get a Class instance from a String?
Yes.
val cls: Class[DoubleAuctionMechanism] = Class.forName("your.app.DoubleAuctionMechanism").asInstanceOf[Class[DoubleAuctionMechanism]]
You would still need the cast, as forName returns Class[_].
Can I instantiate a type with type parameters are not known compile time?
Well sort of, but not really.
object SecuritiesMarket {
def apply[A, C](clsAuc: Class[A], clsClr: Class[C])(security: Security): SecuritiesMarket[A, C] = {
SecuritiesMarket[A, C](security)
}
}
I think auction mechanisms and clearing mechanisms are dependencies for SecurityMarket. I'm guessing you instantiate them in its constructor somehow (how?). If that's the case why not just pass them in as a constructor parameter?
Edit:
I don't see how I could create the child actors inside SecurityMarket
Answering this in the comments; Props[T] can also be written as Props[T](classOfT), which can be simplified as Props(classOfT). Those three are the same. So the following code:
val auctionMechanism: ActorRef = context.actorOf(Props[A], "auction-mechanism")
Can be replaced with:
val classOfA = Class.forName("path.to.A")
val auctionMechanism: ActorRef = context.actorOf(Props(classOfA), "auction-mechanism")
First, application.conf is a runtime artifact and its contents are as far as I know not normally parsed at compile time. When the file is parsed at runtime, the parser creates an instance of the class Config which then controls the Akka setup.
The Typesafe Config library project readme is quite nice and the linked documentation has all of the details:
https://github.com/typesafehub/config/blob/master/README.md.
Second, since template parameters are not available at runtime because of type erasure, you can't normally use application.conf to control templating. You could create a custom build step to parse application.conf and modify your code before compilation, but this is maybe not what you want. (And if you do want a custom build step, perhaps a different .conf would be appropriate.)
Instead you might try simply eliminating the type parameters for the securities market class. Then create a single, simple implementation of the auction and clearing actors. Implement these actors by reading the names of the respective mechanisms from application.conf, instantiating the configured mechanism reflectively, and delegating to the instantiated mechanism. The mechanism classes could be independent of Akka, which is perhaps nice if that's where you keep most of your logic?

Configuring actor behavior using typesafe Config and HOCON

I am building a large agent-based / multi-agent model of a stock exchange using Akka/Play/Scala, etc and I am struggling a bit to understand how to configure my application. Below is a snippet of code that illustrates an example of the type of problem I face:
class Exchange extends Actor {
val orderRoutingLogic = new OrderRoutingLogic()
val router = {
val marketsForSecurities = securities.foreach { security =>
val marketForSecurity = context.actorOf(Props[DoubleAuctionMarket](
new DoubleAuctionMarket(security) with BasicMatchingEngine), security.name
)
orderRoutingLogic.addMarket(security, marketForSecurity)
}
Router(orderRoutingLogic)
}
In the snippet above I inject a BasicMatchingEngine into the DoubleAuctionMarket. However I have written a number of different matching engines and I would like to be able to configure the type of matching engine injected into DoubleAuctionMarket in the application configuration file.
Can this level of application configuration be done using typesafe Config and HOCON configuration files?
interesting case. If I understood you right, you want to configure Market actor mixing in some MatchingEngine type specified in config?
Some clarification: you can't simply mix in dynamic type. I mean if you move MatchingEngine type to config - it will be known only at runtime, when config is parsed. And at that time you'll not be able to instantiate new DoubleAuctionMarket(security) with ???SomeClassInstance???. But maybe you could replace inheritance with aggregation. Maybe an instance of MatchingEngine can be passed to Market as parameter?
Now, how to obtain an instance of MatchingEngine from config? In short - Typesafe Config has no parser for FQCN properties, but it's not hard to do it yourself using reflection. This technique is used in many places in Akka. Look here first. provider property set as fqcn string and can be changed to other provider (i.e. RemoteActorRefProvider) in other configurations. Now look at how it's processed to obtain Provider instance. First it's just being read as string here. Then ProviderClass is used to instantiate actual (runtime) provider here. DynamicAccess is a utility helping with reflexive calls. It's not publicly accessible via context.system, but just take a piece of it or instantiate yourself, I don't think it's a big issue.
With some modifications, your code may look:
class Exchange extends Actor {
val orderRoutingLogic = new OrderRoutingLogic()
val matchingEngineClass = context.system.settings.config.getString("stocks.matching-engine")
val matchingEngine = DynamicAccess.createInstance[MatchingEngine](matchingEngineClass)
val router = {
val marketsForSecurities = securities.foreach { security =>
val marketForSecurity = context.actorOf(DoubleAuctionMarket.props(security, matchingEngine))
orderRoutingLogic.addMarket(security, marketForSecurity)
}
Router(orderRoutingLogic)
}
I've moved props to companion object of DoubleAuctionMarket as stated in Recommended Preactices of akka docs. Usage of Props(new Actor()) is dangerous practice.

Dependency injection with Scala

I was searching a way of doing dependency injection in Scala kind of like Spring or Unity in C# and I found nothing really interesting.
MacWire: I don't understand the benefit as we have to give the class in wire[CASS]. So what's the point if you give the implementation when you call wire? I can do new CASS it will be the same.
Cake pattern with self type: Seems to not answer what I'm searching for.
So I decided to make my implementation and ask you what do you think because it's surprising me that nothing like this has been done before. Maybe my implementation have lot's of issues in real life also.
So here is an example:
trait Messenger {
def send
}
class SkypeMessenger extends Messenger {
def send = println("Skype")
}
class ViberMessenger extends Messenger {
def send = println("Viber")
}
I want here to inject everywhere in my app the implementation configured in only one place:
object App {
val messenger = Inject[Messenger]
def main(args: Array[String]) {
messenger.send
}
}
Note the Inject[Messenger] that I define like below with the config I want (prod or dev):
object Inject extends Injector with DevConfig
trait ProdConfig {
this: Injector =>
register[Messager](new SkypeMessager)
register[Messager](new ViberMessager, "viber")
}
trait DevConfig {
this: Injector =>
register[Messager](new ViberMessager)
register[Messager](new ViberMessager, "viber")
}
And finally here is the Injector which contains all methods apply and register:
class Injector {
var map = Map[String, Any]()
def apply[T: ClassTag] =
map(classTag[T].toString).asInstanceOf[T]
def apply[T: ClassTag](id: String) =
map(classTag[T].toString + id).asInstanceOf[T]
def register[T: ClassTag](instance: T, id: String = "") = {
map += (classTag[T].toString + id -> instance)
instance
}
}
To summaries:
I have a class Injector which is a Map between interfaces/traits (eventually also an id) and an instance of the implementation.
We define a trait for each config (dev, prod...) which contains the registers. It also have a self reference to Injector.
And we create an instance of the Injector with the Config we want
The usage is to call the apply method giving the Interface type (eventually also an id) and it will return the implementation's instance.
What do you think?
You code looks a lot like dependency injection in Lift web framework. You can consult Lift source code to see how it's implemented or just use the framework. You don't have to run a Lift app to use its libraries. Here is a small intro doc. Basically you should be looking at this code in Lift:
package net.liftweb.http
/**
* A base trait for a Factory. A Factory is both an Injector and
* a collection of FactorMaker instances. The FactoryMaker instances auto-register
* with the Injector. This provides both concrete Maker/Vender functionality as
* well as Injector functionality.
*/
trait Factory extends SimpleInjector
You can also check this related question: Scala - write unit tests for objects/singletons that extends a trait/class with DB connection where I show how Lift injector is used.
Thanks guys,
So I make my answer but the one from Aleksey was very good.
I understand better the Cake Pattern with this sample:
https://github.com/freekh/play-slick/tree/master/samples/play-slick-cake-sample
Take a look also to the other implementations without DI and compare:
https://github.com/freekh/play-slick/tree/master/samples/
And so the cake pattern doesn't have a centralized config like we can have with my shown lift style DI. I will anyway use the Cake pattern as it fits well with Slick.
What I didn't like with Subcut is the implicits everywhere. I know there is a way to avoid them but it looks like a fix to me.
Thanks
To comment on MacWire, you are right that you could just use new - and that's the whole point :). MacWire is there only to let you remove some boilerplate from your code, by not having to enumerate all the dependencies again (which is already done in the constructor).
The main idea is that you do the wiring at "the end of the world", where you assemble your application (or you could divide that into trait-modules, but that's optional). Otherwise you just use constructors to express dependencies. No magic, no frameworks.