Consider a code below:
import akka.actor.{ActorSystem, Props}
import akka.io.IO
import spray.can.Http
object Main extends App {
implicit val system = ActorSystem()
val handler = system.actorOf(Props[DemoServiceActor], name = "handler")
IO(Http) ! Http.Bind(handler, interface = "localhost", port = 8080)
}
import akka.actor.Actor
import spray.routing.HttpService
class DemoServiceActor extends Actor with DemoService {
def actorRefFactory = context
def receive = runRoute(demoRoute)
}
trait DemoService extends HttpService {
implicit def executionContext = actorRefFactory.dispatcher
def demoRoute = {
path("test") {
get {
println("ping")
complete("test complete")
}
}
}
}
When main runs it print to console ping. Why? How to fix this?
Related
ive come across this problem :
Caused by: org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
The app works, but i can only make like 3 or 4 requests and then im getting this error, so whats happening (im guessing) is im creating new connections per request and id like to keep one connection per app lifecycle, any idea how to modify the code to do so?
Tried injecting UsersDao to my controller instead of using it as an object but that changes nothing
Im really new to scala so any help is appreciated
Dao
import config.DatabaseConfig
import domain.{User, UsersTable}
import slick.jdbc.PostgresProfile.api._
import slick.sql.SqlAction
import scala.concurrent.Future
trait BaseDao extends DatabaseConfig {
val usersTable = TableQuery[UsersTable]
protected implicit def executeFromDb[A](action: SqlAction[A, NoStream, _ <: slick.dbio.Effect]): Future[A] = {
println(db)
db.run(action)
}
}
object UsersDao extends BaseDao {
def findAll: Future[Seq[User]] = usersTable.result
def create(user: User): Future[Long] = usersTable.returning(usersTable.map(_.id)) += user
def findByFirstName(firstName: String): Future[Seq[User]] = usersTable.filter(_.firstName === firstName).result
def findById(userId: Long): Future[User] = usersTable.filter(_.id === userId).result.head
def delete(userId: Long): Future[Int] = usersTable.filter(_.id === userId).delete
}
DatabaseConfig
trait DatabaseConfig extends Config {
val driver = slick.jdbc.PostgresProfile
import driver.api._
def db = Database.forConfig("dbname")
implicit val session: Session = db.createSession()
}
Controller
import domain.User
import javax.inject.{Inject, Singleton}
import play.api.libs.json.Json
import play.api.mvc._
import repository.UsersDao
import scala.concurrent.{ExecutionContext, Future}
#Singleton
class UserController #Inject() ()(cc: ControllerComponents, parsers: PlayBodyParsers)(implicit exec: ExecutionContext) extends AbstractController(cc) {
def addUser = Action.async(parse.json[User]) { req => {
UsersDao.create(req.body).map({ user =>
Ok(Json.toJson(user))
})
}
}
I would like to be able to create multiple instances of the same parent actor, but with different child actors. I assume this has to be possible with Guice, but I haven't found the solution.
Here is what I have in mind ~
Controller:
class Application #Inject()(#Named(ParentActor.parentActor1) parentActor1: ActorRef,
#Named(ParentActor.parentActor2) parentActor2: ActorRef)
extends Controller {
def index = Action {
parentActor1 ! "Message"
parentActor2 ! "Message"
Ok()
}
}
Parent Actor:
object ParentActor {
final val parentActor1 = "parentActor1"
final val parentActor2 = "parentActor2"
}
class ParentActor #Inject() (childActor: ActorRef) extends Actor {
def receive = {
case "Message" =>
println(s"ParentActor ${self.path} received message...")
childActor ! "Message"
}
}
Child Actor A:
class ChildActorA extends Actor {
def receive = {
case "Message" =>
println("ChildActorA received message...")
}
}
Child Actor B:
class ChildActorB extends Actor {
def receive = {
case "Message" =>
println("ChildActorB received message...")
}
}
Module:
class Modules extends AbstractModule with AkkaGuiceSupport {
override def configure() = {
bindActor[ParentActor](ParentActor.parentActor1)
bindActor[ParentActor](ParentActor.parentActor2)
}
}
What if I wanted "parentActor1" to have have its "childActor" ref point to an instance of ChildActorA and "parentActor2" to have its "childActor" ref point to an instance of ChildActorB? Is this possible to achieve with Guice?
I'm using some code based on https://github.com/rocketraman/activator-akka-scala-guice to accomplish something similar
I'm not using Play, so I have to initialize Guice and bootstrap the actor system
import akka.actor._
import javax.inject.{Inject, Provider, Singleton}
import com.google.inject.AbstractModule
import net.codingwell.scalaguice.InjectorExtensions._
import com.google.inject.Guice
import com.google.inject.Injector
import scala.concurrent.Await
import scala.concurrent.duration.Duration
object Bootstrap extends App {
val injector = Guice.createInjector(
new AkkaModule(),
new ServiceModule()
)
implicit val system = injector.instance[ActorSystem]
val parentActor1 = system.actorOf(ParentActor.props(ChildActorA.name))
val parentActor2 = system.actorOf(ParentActor.props(ChildActorB.name))
parentActor1 ! "Message"
parentActor2 ! "Message"
system.terminate()
Await.result(system.whenTerminated, Duration.Inf)
}
To initialize Guice there are two classes/objects:
One to initialize the extension and inject the actor system where required
import akka.actor.ActorSystem
import AkkaModule.ActorSystemProvider
import com.google.inject.{AbstractModule, Injector, Provider}
import com.typesafe.config.Config
import net.codingwell.scalaguice.ScalaModule
import javax.inject.Inject
object AkkaModule {
class ActorSystemProvider #Inject() (val injector: Injector) extends Provider[ActorSystem] {
override def get() = {
val system = ActorSystem("actor-system")
GuiceAkkaExtension(system).initialize(injector)
system
}
}
}
class AkkaModule extends AbstractModule with ScalaModule {
override def configure() {
bind[ActorSystem].toProvider[ActorSystemProvider].asEagerSingleton()
}
}
another one to create the providers for the children
import javax.inject.Inject
import akka.actor.{Actor, ActorRef, ActorSystem}
import com.google.inject.name.{Named, Names}
import com.google.inject.{AbstractModule, Provides, Singleton}
import net.codingwell.scalaguice.ScalaModule
class ServiceModule extends AbstractModule with ScalaModule with GuiceAkkaActorRefProvider {
override def configure() {
bind[Actor].annotatedWith(Names.named(ChildActorA.name)).to[ChildActorA]
bind[Actor].annotatedWith(Names.named(ChildActorB.name)).to[ChildActorB]
}
#Provides
#Named(ChildActorA.name)
def provideChildActorARef(#Inject() system: ActorSystem): ActorRef = provideActorRef(system, ChildActorA.name)
#Provides
#Named(ChildActorB.name)
def provideChildActorBRef(#Inject() system: ActorSystem): ActorRef = provideActorRef(system, ChildActorB.name)
}
The extension
import akka.actor._
import com.google.inject.Injector
class GuiceAkkaExtensionImpl extends Extension {
private var injector: Injector = _
def initialize(injector: Injector) {
this.injector = injector
}
def props(actorName: String) = Props(classOf[GuiceActorProducer], injector, actorName)
}
object GuiceAkkaExtension extends ExtensionId[GuiceAkkaExtensionImpl] with ExtensionIdProvider {
override def lookup() = GuiceAkkaExtension
override def createExtension(system: ExtendedActorSystem) = new GuiceAkkaExtensionImpl
override def get(system: ActorSystem): GuiceAkkaExtensionImpl = super.get(system)
}
trait NamedActor {
def name: String
}
trait GuiceAkkaActorRefProvider {
def propsFor(system: ActorSystem, name: String) = GuiceAkkaExtension(system).props(name)
def provideActorRef(system: ActorSystem, name: String): ActorRef = system.actorOf(propsFor(system, name))
}
producer
import akka.actor.{IndirectActorProducer, Actor}
import com.google.inject.name.Names
import com.google.inject.{Key, Injector}
class GuiceActorProducer(val injector: Injector, val actorName: String) extends IndirectActorProducer {
override def actorClass = classOf[Actor]
override def produce() = injector.getBinding(Key.get(classOf[Actor], Names.named(actorName))).getProvider.get()
}
and your actors
import javax.inject.Inject
import akka.actor._
object ParentActor {
def props(childName: String)(implicit #Inject() system: ActorSystem) = Props(classOf[ParentActor],system.actorOf(GuiceAkkaExtension(system).props(childName)))
}
class ParentActor (childActor: ActorRef) extends Actor {
def receive = {
case "Message" =>
println(s"ParentActor ${self.path} received message...")
childActor ! "Message"
}
}
object ChildActorA extends NamedActor{
override final val name = "ChildActorA"
def props() = Props(classOf[ChildActorA])
}
class ChildActorA extends Actor {
def receive = {
case "Message" =>
println("ChildActorA received message...")
}
}
object ChildActorB extends NamedActor{
override final val name = "ChildActorB"
def props() = Props(classOf[ChildActorB])
}
class ChildActorB extends Actor {
def receive = {
case "Message" =>
println("ChildActorB received message...")
}
}
the output from sbt
> run
[info] Running Bootstrap
ParentActor akka://actor-system/user/$b received message...
ParentActor akka://actor-system/user/$d received message...
ChildActorB received message...
ChildActorA received message...
[success] Total time: 1 s, completed Jun 14, 2016 1:23:59 AM
You have to explicitly name the children,
It's not the purest or most elegant answer, and I'm sure the code can be optimized, but it allows you to create instances of the same parent with different children.
I'm thinking that you can also use BindingAnnotations
I'm using Play Scala 2.5, I would like to write functional tests for a controller class.
This is the signature of my controller class with a action I would like to test for example.
class MyController #Inject()(implicit context: ExecutionContext, val messagesApi: MessagesApi, val dao: Dao) extends Controller with I18nSupport {
def getMyData = Action.async { implicit request =>
dao.getMyData map { myData =>
Ok(views.html.render(myData))
}.recover {
// recover.
}
}
}
Here is my Dao class that is used in my controller's action :
import play.api.Configuration
class Dao #Inject()(val ws: WSClient, val configuration: Configuration) {
val myConfigData: List[MyConfigData] = { ... } // Get data from configuration
def getMyData(): Future[List[MyData]] = {
// use myConfigData and call web service (ws) to get some data
}
}
I would like to test my controller's action using different configuration in my Dao class.
I manage to do it and my test class is working but I would like some advices to improve the code.
package controllers
import play.core.server.Server
import org.scalatest._
import Inspectors._
import org.scalatestplus.play._
import play.api.routing.sird._
import play.api.libs.json._
import play.api.mvc._
import play.api.Play
import play.api.test._
import play.api.i18n.MessagesApi
import play.api.Configuration
import play.api.test.Helpers.{ OK, status, contentAsString }
import org.scalatest.concurrent.ScalaFutures
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.duration._
import play.api.libs.json._
import play.api.mvc._
import scala.concurrent.ExecutionContext
import com.typesafe.config.ConfigFactory
import dao.{ Dao }
import akka.util.Timeout
class MyControllerFunctionalSpec extends PlaySpec with OneAppPerSuite with ScalaFutures {
implicit val messagesApi = app.injector.instanceOf[MessagesApi]
implicit val ec = app.injector.instanceOf[ExecutionContext]
implicit val timeout = Timeout(5 seconds)
trait OneConfig {
val config = ConfigFactory.parseString(""" my config """)
}
trait AnotherConfig {
val config = ConfigFactory.parseString(""" my other config """)
}
"MyController" should {
"get some data" in new OneConfig {
Server.withRouter() {
case GET(p"/url1/some/data") => Action {
Results.Ok(Json.arr(Json.obj("name" -> "data1")))
}
} { implicit port =>
WsTestClient.withClient { client =>
implicit val dao = new Dao(client, Configuration(config))
val myController = new MyController()
val result = myController.getMyData(FakeRequest())
status(result) must equal(OK)
//println(contentAsString(result))
}
}
}
}
}
It is working like this but I was guided by compilation error and by fixing them to get it to work.
I would like help or advices to do it the right way.
Any advice welcome.
I am using akka-http 1.0 and I would like to use a route defined as
def route: Route = path("") {
// start actor with requestContext
// call requestContext.complete(...) in actor with the result
}
How do I accomplish this?
Elaborating on #jrudolph's comment, the below code satisfies your requirements of dispatching RequestContext values to an Actor. Your question indicated that you wanted a new Actor for each request; however, the below code uses the same Actor for all requests which I think is a more efficient/likely use case. The Actor creation can always be moved inside handleRequest if needed.
First we need an Actor for processing a request to a response:
import akka.actor.Actor
import akka.http.scaladsl.server.{RequestContext, RouteResult}
import akka.http.scaladsl.model.HttpResponse
class RequestActor extends Actor {
//business logic - returns empty HttpResponse
def handleRequestMessage(requestContext : RequestContext) =
RouteResult.Complete(new HttpResponse())
override def receive = {
case reqContext : RequestContext =>
sender ! handleRequestMessage(reqContext)
}
}//end class RequestActor
Now create a utility function for querying the Actor:
import akka.actor.ActorRef
import scala.concurrent.Future
import akka.pattern.ask
object RequestActor {
val handleRequest : ActorRef => RequestContext => Future[RouteResult] =
(actorRef) =>
(requestContext) =>
ask(actorRef,reqContext).mapTo[RouteResult]
}
And all that is left to do is wire everything together into a service:
import akka.actor.{ActorSystem, Props}
import akka.stream.ActorMaterializer
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives.{get,path}
import akka.util.Timeout
object RouteActorTest extends App {
implicit val as = ActorSystem("RouteActorTest")
implicit val timeout = new Timeout(1000)
val sendRequestToActor : RequestContext => Future[RouteResult] =
RequestActor handleRequest (as actorOf Props[RequestActor])
val route = path("")(get(sendRequestToActor))
//rest of application...
}//end object RouteActorTest
you may try even better like:
package controllers
import akka.actor.{Actor, ActorSystem, Props}
import akka.stream.ActorMaterializer
import scala.concurrent.{Await, Future}
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.util.Timeout
import akka.pattern.ask
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn
import akka.actor._
import akka.util.Timeout
case object Message
class TestActor(name:String) extends Actor {
def receive = {
case Message =>
sender ! "Testing Ask pattern Approach"
println(s"hello from $name")
case _ =>
println("that was unexpected")
}
}
object AskTest extends App {
implicit val system= ActorSystem("myactor")
implicit val material=ActorMaterializer()
// implicit val props=Props.empty
implicit val timeout = Timeout(5 seconds)
implicit val result =system.actorOf(Props(new TestActor("TestingName")),name = "Scala")
val future3:Future[String]= ask(result ,Message).mapTo[String]
val results = Await.result(future3, 2 seconds)
println(results)
}
I have this trait
trait NonBlockingGoodness extends DataStore {
import akka.dispatch.{ Future, ExecutionContext }
import akka.util.duration._
import akka.util.Timeout
implicit val ec = ExecutionContext.fromExecutorService(yourExecutorServiceGoesHere)
implicit lazy val timeout = Timeout(5 seconds)
}
I would like to access the ExecutionContext in another trait like such
trait AsyncGoodness extends NonBlockingGoodness {
import akka.dispatch.Future
def doSomething = {
Future { "Future is the bomb." }
}
However, I am getting the error
Could not find implicit value for parameter executor: akka.dispatch.ExecutionContext
UPDATED:
I figured out how to get the ExecutionContext in scope
trait AsyncGoodness extends NonBlockingGoodness {
import akka.dispatch.ExecutionContext
import akka.dispatch.Future
def doSomething()(implicit executor: ExecutionContext) = {
Future { "Future is the bomb." }
}
However, I have a follow-up question. Since I may have more than 1 method in AsyncGoodness that uses ExecutionContext, is there a way to pass it in at the trait level instead of at each method like I did above.
I know you'd rather not have to import anything extra, but something like this should work for you.
trait NonBlockingGoodness {
import scala.concurrent.{ Future, ExecutionContext }
import scala.concurrent.util.duration._
import akka.util.Timeout
object Implicit {
implicit val ec = ExecutionContext.Implicits.global
implicit lazy val timeout = Timeout(5 seconds)
}
}
trait AsyncGoodness extends NonBlockingGoodness {
import scala.concurrent.Future
import Implicit._
def doSomething = {
Future { "Future is the bomb." }
}
}
As it turns out, all I need to do is explicitly specify ec return type for the compiler to use it. Here's the working code
trait NonBlockingGoodness extends DataStore {
import akka.dispatch.{ Future, ExecutionContext }
import akka.util.duration._
import akka.util.Timeout
implicit val ec: ExecutionContext = ExecutionContext.fromExecutorService(yourExecutorServiceGoesHere)
implicit lazy val timeout = Timeout(5 seconds)
}
trait AsyncGoodness extends NonBlockingGoodness {
import akka.dispatch.Future
def doSomething = {
Future { "Future is the bomb." }
}