SlideShare a Scribd company logo
1 of 50
Download to read offline
a million bots can't be wrong
               @remeniuk, Viaden Media
                   #ScalaSBP, 18-05-2012
In Viaden our aim is to make the best poker ever
we know that
performance tests should be
   the first-class citizens
and kill 2 birds with one stone,
     using bots for testing
 
#1 we can emulate 50k
players using just one
medium EC2 instance
 
#2 bots are interactive,
so client teams can use
them in development,
and QA for testing
everyone knows Akka, huh?
why Scala and Akka is a perfect
   choice for making bots?


actors are !(interactive)
straightforward remoting
simple scalability/clustering
~30 minutes to make a DSL and CLI
with Scala and SBT
..., but, I have to warn you ...
4 dead simple tips
     for keeping your sanity
when you do asynch with Akka 2.0
tip #1: live fast, die young
typical approach in Akka 1.x


                      lobby

                                desk
login
              l ink
        bot




                                  tourney
Akka 1.x: actors have a long lifecycle


                              lobby

                                        desk
            l ink        nk
      bot             li
                    un
                                l ink
play game
            bot
                                          tourney
Akka 1.x: actors have a long lifecycle


                        lobby

                                         desk
      bot




                                     k
                                 lin
                  bot

                                un
                                           tourney
play tournament                  link
                        bot
in Akka 2.0 the world has changed


               props
     paths
                          new
                       supervision
             actors
now, you're forced to do "the right thing" (c)



                     lobby
                                        desk
        tournament

                                       DeskBot
           desk

          DeskBot

                             IdleBot
all actors are supervised




       lobby

                              login
desk
easy come




       lobby

desk
                         play game
               IdleBot
easy go (when supervisor to be changed)




             lobby


      desk
                     IdleBot   dies
    DeskBot


     borns
class Lobby extends Actor {

    case Login(username, password) =>
          context.actorOf(Props(new IdlePokerBot(...)))

    case JoinAnyDesk(props) => findDesk ! JoinDesk(props)

}

class Desk extends Actor {

    case JoinDesk(botProps)=>
         context.actorOf(Props(new DeskPokerBot(botProps)))

}

class IdlePokerBot(props: BotProps) extends Actor {

    case PlayNow =>
       context.parent ! JoinAnyDesk(props); context.stop(self)

}
Props Pattern - "the soul" of an actor

                         IdleBot

                         BotProps
Props remains alive
between actor
"reincarnations"

                         DeskBot

                         BotProps
case class BotProperties(id: Long,
                         login: String,
                         script: Seq[BotEvent],
                         aggressiveness: Int,
                         sessionId: Protocol.SessionId)



class IdlePokerBot(val botProperties: BotProperties)
                                            extends Bot[Poker]


class DeskPokerBot(val botProperties: BotProperties)
                                            extends Bot[Poker]
tip #2: think beyond
when you know, who's supervising, life's
simple

 akka://gpdev/user/lobby/player1234



 akka://gpdev/user/lobby/desk1/player1234



 akka://gpdev/user/lobby/tournament1/desk1/
 player1234
Bad news
ActorRegistry, actor UUID
        were removed from Akka




but what should I do, now,
when I don't know, where
to look for my bot?
you can make your own registry
(using Extensions, backed with a
distributed data structure)...
or, use the full power of location transparency


                                Projection
         lobby                   Manager

                                Projection
          desk                   var location:
                                  ActorPath

         DeskBot


                           /projection/player123
         IdleBot         /lobby/desk123/player123
class Projection(var container: ActorPath) extends Actor {

  def receive = {
    case newContainer: ActorPath => container = newContainer
    case msg =>
          context.actorFor(container.child(self.path.name)) !
msg
  }

}

class ProjectionManager extends Actor {

    def receive = {
      case Add(actor) => context.actorOf(Props(new
                Projection(actor.path.parent)), actor.path.name)
      case Forward(msg, path) => context.actorFor(path) ! msg
    }

}


projectionManager ! Add(actorRef)
projectionManager ! Forward("ping", "actor1")
class Projection(var container: ActorPath) extends Actor {

    def receive = {
      case newContainer: ActorPath => container = newContainer
      case msg =>
            context.actorFor(container.child(self.path.name)) ! msg
    }

}

class ProjectionManager extends Actor {

    def receive = {
      case Add(actor) => context.actorOf(Props(new
                Projection(actor.path.parent)), actor.path.name)
      case Forward(msg, path) => context.actorFor(path) ! msg
    }

}


projectionManager ! Add(actorRef)
system.actorFor(projectionManager.path.child("actor" + i)) !
"ping"
class ProjectionManager extends Actor {

    def receive = {
      case Add(actor) => context.actorOf(Props(new
                Projection(actor.path.parent)), actor.path.name)
      case Forward(msg, path) =>
                    context.actorSelection("../*/" + path) ! msg
    }

}


val projectionManager = system.actorOf(Props
[ProjectionManagerRoutee]
        .withRouter(RoundRobinRouter(resizer = Some
    (DefaultResizer(lowerBound = 10, upperBound = 20)))),
    "projection")


projectionManager ! Add(actorRef)
projectionManager ! Forward("ping", "actor1")
case class CustomRouter(n: Int, routerDispatcher: String =
DefaultDispatcherId, supervisorStrategy: SupervisorStrategy =
defaultStrategy) extends RouterConfig {

    def createRoute(props: Props, provider: RouteeProvider) = {

    provider.registerRoutees((1 to n).map(i =>
   provider.context.actorOf(Props[ProjectionManager], i.
toString)))

    def destination(sender: ActorRef, path: String) =
      List(Destination(sender,
                        provider.routees(abs(path.hashCode) %
n)))

        {
            case m@(sender, Add(actor)) ⇒
                                 destination(sender, actor.path.name)
            case m@(sender, Forward(_, name)) ⇒
                                 destination(sender, name)
        }
    }

}
tip #3: don't do anything stupid
you've tried all the options, system load is fine,
only 1/10 of the heap is used, but you still can
start not more than 1k bots!?
ulimit -n <proper value>
your actor is lacking of throughput?
 
 
 
 
 
 
 
wait before adding pools
share responsibility!
one fine-grained actor is enough in 99% of the cases
100-300 threads are serving 300 bots!?
spawn futures, backed with standalone
[bounded] pools, for blocking operations

 class ThirdPartyWrapper extends Actor {

     case F(x) => sender ! thirdPartyService.f(x)
 // call to a function that takes a lot of time to
 // complete

 }



class ThirdPartyWrapper extends Actor {

     case F(x) => val _sender = sender
         Future(thirdPartyService.f(x)).map(_sender ! _)
         // ugly, but safe, and perfectly right
}
use separate dispatchers
lobby-dispatcher                       projection-manager-dispatcher
PinnedDispatcher                       BalancingDispatcher




               lobby                             Projection
                                                  Manager
                   desk
                                                 Projection
                                                         
               DeskBot

                                                projection-dispatcher
container-dispatcher      desk-bot-dispatcher Dispatcher
Dispatcher                Dispatcher
GOTCHA: Akka successfully bootstraps, even if your
dispatcher is not configured, or the config is wrong
 
Always check the logs to make sure that dispatchers are used!

  [WARN][gpdev-akka.actor.default-dispatcher-1] [Dispatchers]
  Dispatcher [bot-system.container-dispatcher] not
  configured, using default-dispatcher
  [WARN][gpdev-bot-system.container-dispatcher-1]
  [PinnedDispatcherConfigurator] PinnedDispatcher [bot-
  system.lobby-dispatcher] not configured to use
  ThreadPoolExecutor, falling back to default config.

  [DEBUG][gpdev-akka.actor.default-dispatcher-24] [akka:
  //gpdev/user/poker/lobby] logged in
  [DEBUG][gpdev-akka.actor.default-dispatcher-14] [akka:
  //gpdev/user/poker/projeciton/$g/player20013] starting
  projection...
tip #4: analyze that
how to measure?
 
Metrics - pushes various collected metrics to Graphite
Carbon and Graphite - gather metrics, and expose them via web
interface
 
object BotMetrics {

1. val   loggedInCount = new Counter(Metrics.newCounter(classOf[Lobby
[_]],
                                       "logged-in-count"))

3. GraphiteReporter.enable(1,   TimeUnit.MINUTES, "localhost", 2003)

}

class Lobby extends Actor {

2. case   Login(username, pass) => BotMetrics.loggedInCount += 1

}


1. add logged-in user counter                                      4.
2. update it
3. enable reporting to
Graphite
4. build a graph in Grtaphite
what to measure?
     
    - mailbox size1
    - throughput
    - time, before the message is processed (both in
    actor and future)2
    - time to process a message
    - count of threads
    - actor pool size
    - heap size




1
    requires implementation of a custom mailbox that can expose mailbox size
2
    every message should be stuffed with a timestamp
how to tune dispatchers?
 
VisualVM - thread timeline shows, if thread polls behind dispatchers
are used effectively
 
don't neglect old good logging
 
[ERROR][05/06/2012 12:55:43.826] [gpdev-bot-system.
desk-bot-dispatcher-7]
[akka://gpdev/user/
poker/lobby/tournament5382577/desk109129/player2012
1]
unprocessed game event: GameEvent(CHAT,None,None)
thanks for listening
we're hiring!
viaden.com/careers/vacancies.html

More Related Content

What's hot

Run commands listed below in alphabetical order
Run commands listed below in alphabetical orderRun commands listed below in alphabetical order
Run commands listed below in alphabetical orderKondareddy Settipalli
 
Oral presentation v2
Oral presentation v2Oral presentation v2
Oral presentation v2Yeqi He
 
2013 gr8 conf_grails_code_from_the_trenches
2013 gr8 conf_grails_code_from_the_trenches2013 gr8 conf_grails_code_from_the_trenches
2013 gr8 conf_grails_code_from_the_trenchesEdwin van Nes
 
libGDX: Screens, Fonts and Preferences
libGDX: Screens, Fonts and PreferenceslibGDX: Screens, Fonts and Preferences
libGDX: Screens, Fonts and PreferencesJussi Pohjolainen
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script ProgrammingLin Yo-An
 
Rapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjectsRapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjectsGiorgio Pomettini
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with GroovyJames Williams
 
Emacs presentation
Emacs presentationEmacs presentation
Emacs presentationLingfei Kong
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go ProgrammingLin Yo-An
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareKuan Yen Heng
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012Martin Schuhfuß
 

What's hot (20)

ReUse Your (Puppet) Modules!
ReUse Your (Puppet) Modules!ReUse Your (Puppet) Modules!
ReUse Your (Puppet) Modules!
 
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
 
Run commands listed below in alphabetical order
Run commands listed below in alphabetical orderRun commands listed below in alphabetical order
Run commands listed below in alphabetical order
 
6202942
62029426202942
6202942
 
Puppet modules for Fun and Profit
Puppet modules for Fun and ProfitPuppet modules for Fun and Profit
Puppet modules for Fun and Profit
 
Oral presentation v2
Oral presentation v2Oral presentation v2
Oral presentation v2
 
2013 gr8 conf_grails_code_from_the_trenches
2013 gr8 conf_grails_code_from_the_trenches2013 gr8 conf_grails_code_from_the_trenches
2013 gr8 conf_grails_code_from_the_trenches
 
libGDX: Screens, Fonts and Preferences
libGDX: Screens, Fonts and PreferenceslibGDX: Screens, Fonts and Preferences
libGDX: Screens, Fonts and Preferences
 
Troubleshooting Puppet
Troubleshooting PuppetTroubleshooting Puppet
Troubleshooting Puppet
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
Rapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjectsRapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjects
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with Groovy
 
Expression Language 3.0
Expression Language 3.0Expression Language 3.0
Expression Language 3.0
 
Emacs presentation
Emacs presentationEmacs presentation
Emacs presentation
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go Programming
 
Power of Puppet 4
Power of Puppet 4Power of Puppet 4
Power of Puppet 4
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
Kotlin intro
Kotlin introKotlin intro
Kotlin intro
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012
 

Viewers also liked

Advances in Game AI
Advances in Game AIAdvances in Game AI
Advances in Game AILuke Dicken
 
Computationally Viable Handling of Beliefs in Arguments for Persuasion
Computationally Viable Handling of Beliefs in Arguments for PersuasionComputationally Viable Handling of Beliefs in Arguments for Persuasion
Computationally Viable Handling of Beliefs in Arguments for PersuasionEmmanuel Hadoux
 
The Strathclyde Poker Research Environment
The Strathclyde Poker Research EnvironmentThe Strathclyde Poker Research Environment
The Strathclyde Poker Research EnvironmentLuke Dicken
 
Poker, packets, pipes and Python
Poker, packets, pipes and PythonPoker, packets, pipes and Python
Poker, packets, pipes and PythonRoger Barnes
 
"Bwin - P5 a future proof Poker platform"
"Bwin - P5 a future proof Poker platform""Bwin - P5 a future proof Poker platform"
"Bwin - P5 a future proof Poker platform"gerold kathan
 
Poker in Numbers
Poker in NumbersPoker in Numbers
Poker in NumbersPokerCoUk
 
AI Strategies for Solving Poker Texas Hold'em
AI Strategies for Solving Poker Texas Hold'emAI Strategies for Solving Poker Texas Hold'em
AI Strategies for Solving Poker Texas Hold'emGiovanni Murru
 

Viewers also liked (10)

Advances in Game AI
Advances in Game AIAdvances in Game AI
Advances in Game AI
 
Computationally Viable Handling of Beliefs in Arguments for Persuasion
Computationally Viable Handling of Beliefs in Arguments for PersuasionComputationally Viable Handling of Beliefs in Arguments for Persuasion
Computationally Viable Handling of Beliefs in Arguments for Persuasion
 
The Strathclyde Poker Research Environment
The Strathclyde Poker Research EnvironmentThe Strathclyde Poker Research Environment
The Strathclyde Poker Research Environment
 
Poker, packets, pipes and Python
Poker, packets, pipes and PythonPoker, packets, pipes and Python
Poker, packets, pipes and Python
 
"Bwin - P5 a future proof Poker platform"
"Bwin - P5 a future proof Poker platform""Bwin - P5 a future proof Poker platform"
"Bwin - P5 a future proof Poker platform"
 
Poker maths
Poker mathsPoker maths
Poker maths
 
The Art Of War In Poker
The Art Of War In PokerThe Art Of War In Poker
The Art Of War In Poker
 
Poker in Numbers
Poker in NumbersPoker in Numbers
Poker in Numbers
 
Minimax
MinimaxMinimax
Minimax
 
AI Strategies for Solving Poker Texas Hold'em
AI Strategies for Solving Poker Texas Hold'emAI Strategies for Solving Poker Texas Hold'em
AI Strategies for Solving Poker Texas Hold'em
 

Similar to Bots Testing Scala Akka Performance

Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
 
First glance at Akka 2.0
First glance at Akka 2.0First glance at Akka 2.0
First glance at Akka 2.0Vasil Remeniuk
 
GR8Conf 2011: GPars
GR8Conf 2011: GParsGR8Conf 2011: GPars
GR8Conf 2011: GParsGR8Conf
 
Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"Hyuk Hur
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 
Online game server on Akka.NET (NDC2016)
Online game server on Akka.NET (NDC2016)Online game server on Akka.NET (NDC2016)
Online game server on Akka.NET (NDC2016)Esun Kim
 
The dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetupThe dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetupkrivachy
 
ruby2600 - an Atari 2600 emulator written in Ruby
ruby2600 - an Atari 2600 emulator written in Rubyruby2600 - an Atari 2600 emulator written in Ruby
ruby2600 - an Atari 2600 emulator written in RubyCarlos Duarte do Nascimento
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyGolang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyAerospike
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And BeyondMike Fogus
 
Akka Actors: an Introduction
Akka Actors: an IntroductionAkka Actors: an Introduction
Akka Actors: an IntroductionRoberto Casadei
 
From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017Agustin Ramos
 
Akka: Distributed by Design
Akka: Distributed by DesignAkka: Distributed by Design
Akka: Distributed by Designpatriknw
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowViliam Elischer
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaFunctional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaPhilip Schwarz
 

Similar to Bots Testing Scala Akka Performance (20)

Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
First glance at Akka 2.0
First glance at Akka 2.0First glance at Akka 2.0
First glance at Akka 2.0
 
GR8Conf 2011: GPars
GR8Conf 2011: GParsGR8Conf 2011: GPars
GR8Conf 2011: GPars
 
XRobots
XRobotsXRobots
XRobots
 
Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
 
Akka JUGL 2012
Akka JUGL 2012Akka JUGL 2012
Akka JUGL 2012
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
Online game server on Akka.NET (NDC2016)
Online game server on Akka.NET (NDC2016)Online game server on Akka.NET (NDC2016)
Online game server on Akka.NET (NDC2016)
 
The dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetupThe dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetup
 
ruby2600 - an Atari 2600 emulator written in Ruby
ruby2600 - an Atari 2600 emulator written in Rubyruby2600 - an Atari 2600 emulator written in Ruby
ruby2600 - an Atari 2600 emulator written in Ruby
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyGolang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war story
 
Akka (BeJUG)
Akka (BeJUG)Akka (BeJUG)
Akka (BeJUG)
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
Akka Actors: an Introduction
Akka Actors: an IntroductionAkka Actors: an Introduction
Akka Actors: an Introduction
 
From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017
 
Akka: Distributed by Design
Akka: Distributed by DesignAkka: Distributed by Design
Akka: Distributed by Design
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrow
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaFunctional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala
 

More from Vasil Remeniuk

Product Minsk - РТБ и Программатик
Product Minsk - РТБ и ПрограмматикProduct Minsk - РТБ и Программатик
Product Minsk - РТБ и ПрограмматикVasil Remeniuk
 
Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Vasil Remeniuk
 
Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14Vasil Remeniuk
 
Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3Vasil Remeniuk
 
Testing in Scala by Adform research
Testing in Scala by Adform researchTesting in Scala by Adform research
Testing in Scala by Adform researchVasil Remeniuk
 
Spark Intro by Adform Research
Spark Intro by Adform ResearchSpark Intro by Adform Research
Spark Intro by Adform ResearchVasil Remeniuk
 
Types by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaTypes by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaVasil Remeniuk
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform ResearchVasil Remeniuk
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovVasil Remeniuk
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovVasil Remeniuk
 
Spark by Adform Research, Paulius
Spark by Adform Research, PauliusSpark by Adform Research, Paulius
Spark by Adform Research, PauliusVasil Remeniuk
 
Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)Vasil Remeniuk
 
Spark intro by Adform Research
Spark intro by Adform ResearchSpark intro by Adform Research
Spark intro by Adform ResearchVasil Remeniuk
 
SBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius ValatkaSBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius ValatkaVasil Remeniuk
 
Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2Vasil Remeniuk
 
Testing in Scala. Adform Research
Testing in Scala. Adform ResearchTesting in Scala. Adform Research
Testing in Scala. Adform ResearchVasil Remeniuk
 
Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1Vasil Remeniuk
 
Cassandra + Spark + Elk
Cassandra + Spark + ElkCassandra + Spark + Elk
Cassandra + Spark + ElkVasil Remeniuk
 
Опыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхОпыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхVasil Remeniuk
 

More from Vasil Remeniuk (20)

Product Minsk - РТБ и Программатик
Product Minsk - РТБ и ПрограмматикProduct Minsk - РТБ и Программатик
Product Minsk - РТБ и Программатик
 
Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14
 
Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14
 
Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3
 
Testing in Scala by Adform research
Testing in Scala by Adform researchTesting in Scala by Adform research
Testing in Scala by Adform research
 
Spark Intro by Adform Research
Spark Intro by Adform ResearchSpark Intro by Adform Research
Spark Intro by Adform Research
 
Types by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaTypes by Adform Research, Saulius Valatka
Types by Adform Research, Saulius Valatka
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform Research
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex Gryzlov
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex Gryzlov
 
Spark by Adform Research, Paulius
Spark by Adform Research, PauliusSpark by Adform Research, Paulius
Spark by Adform Research, Paulius
 
Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)
 
Spark intro by Adform Research
Spark intro by Adform ResearchSpark intro by Adform Research
Spark intro by Adform Research
 
SBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius ValatkaSBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius Valatka
 
Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2
 
Testing in Scala. Adform Research
Testing in Scala. Adform ResearchTesting in Scala. Adform Research
Testing in Scala. Adform Research
 
Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1
 
Cassandra + Spark + Elk
Cassandra + Spark + ElkCassandra + Spark + Elk
Cassandra + Spark + Elk
 
Опыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхОпыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событиях
 
ETL со Spark
ETL со SparkETL со Spark
ETL со Spark
 

Recently uploaded

Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 

Recently uploaded (20)

Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

Bots Testing Scala Akka Performance

  • 1. a million bots can't be wrong @remeniuk, Viaden Media #ScalaSBP, 18-05-2012
  • 2. In Viaden our aim is to make the best poker ever
  • 3. we know that performance tests should be the first-class citizens
  • 4. and kill 2 birds with one stone, using bots for testing
  • 5.   #1 we can emulate 50k players using just one medium EC2 instance   #2 bots are interactive, so client teams can use them in development, and QA for testing
  • 7. why Scala and Akka is a perfect choice for making bots? actors are !(interactive) straightforward remoting simple scalability/clustering ~30 minutes to make a DSL and CLI with Scala and SBT
  • 8. ..., but, I have to warn you ...
  • 9. 4 dead simple tips for keeping your sanity when you do asynch with Akka 2.0
  • 10. tip #1: live fast, die young
  • 11. typical approach in Akka 1.x lobby desk login l ink bot tourney
  • 12. Akka 1.x: actors have a long lifecycle lobby desk l ink nk bot li un l ink play game bot tourney
  • 13. Akka 1.x: actors have a long lifecycle lobby desk bot k lin bot un tourney play tournament link bot
  • 14. in Akka 2.0 the world has changed props paths new supervision actors
  • 15. now, you're forced to do "the right thing" (c) lobby desk tournament DeskBot desk DeskBot IdleBot
  • 16. all actors are supervised lobby login desk
  • 17. easy come lobby desk play game IdleBot
  • 18. easy go (when supervisor to be changed) lobby desk IdleBot dies DeskBot borns
  • 19. class Lobby extends Actor { case Login(username, password) => context.actorOf(Props(new IdlePokerBot(...))) case JoinAnyDesk(props) => findDesk ! JoinDesk(props) } class Desk extends Actor { case JoinDesk(botProps)=> context.actorOf(Props(new DeskPokerBot(botProps))) } class IdlePokerBot(props: BotProps) extends Actor { case PlayNow => context.parent ! JoinAnyDesk(props); context.stop(self) }
  • 20. Props Pattern - "the soul" of an actor IdleBot BotProps Props remains alive between actor "reincarnations" DeskBot BotProps
  • 21. case class BotProperties(id: Long, login: String, script: Seq[BotEvent], aggressiveness: Int, sessionId: Protocol.SessionId) class IdlePokerBot(val botProperties: BotProperties) extends Bot[Poker] class DeskPokerBot(val botProperties: BotProperties) extends Bot[Poker]
  • 22. tip #2: think beyond
  • 23. when you know, who's supervising, life's simple akka://gpdev/user/lobby/player1234 akka://gpdev/user/lobby/desk1/player1234 akka://gpdev/user/lobby/tournament1/desk1/ player1234
  • 24. Bad news ActorRegistry, actor UUID were removed from Akka but what should I do, now, when I don't know, where to look for my bot?
  • 25. you can make your own registry (using Extensions, backed with a distributed data structure)...
  • 26. or, use the full power of location transparency Projection lobby Manager Projection desk var location: ActorPath DeskBot /projection/player123 IdleBot /lobby/desk123/player123
  • 27. class Projection(var container: ActorPath) extends Actor { def receive = { case newContainer: ActorPath => container = newContainer case msg => context.actorFor(container.child(self.path.name)) ! msg } } class ProjectionManager extends Actor { def receive = { case Add(actor) => context.actorOf(Props(new Projection(actor.path.parent)), actor.path.name) case Forward(msg, path) => context.actorFor(path) ! msg } } projectionManager ! Add(actorRef) projectionManager ! Forward("ping", "actor1")
  • 28.
  • 29. class Projection(var container: ActorPath) extends Actor { def receive = { case newContainer: ActorPath => container = newContainer case msg => context.actorFor(container.child(self.path.name)) ! msg } } class ProjectionManager extends Actor { def receive = { case Add(actor) => context.actorOf(Props(new Projection(actor.path.parent)), actor.path.name) case Forward(msg, path) => context.actorFor(path) ! msg } } projectionManager ! Add(actorRef) system.actorFor(projectionManager.path.child("actor" + i)) ! "ping"
  • 30.
  • 31. class ProjectionManager extends Actor { def receive = { case Add(actor) => context.actorOf(Props(new Projection(actor.path.parent)), actor.path.name) case Forward(msg, path) => context.actorSelection("../*/" + path) ! msg } } val projectionManager = system.actorOf(Props [ProjectionManagerRoutee] .withRouter(RoundRobinRouter(resizer = Some (DefaultResizer(lowerBound = 10, upperBound = 20)))), "projection") projectionManager ! Add(actorRef) projectionManager ! Forward("ping", "actor1")
  • 32.
  • 33. case class CustomRouter(n: Int, routerDispatcher: String = DefaultDispatcherId, supervisorStrategy: SupervisorStrategy = defaultStrategy) extends RouterConfig { def createRoute(props: Props, provider: RouteeProvider) = { provider.registerRoutees((1 to n).map(i => provider.context.actorOf(Props[ProjectionManager], i. toString))) def destination(sender: ActorRef, path: String) = List(Destination(sender, provider.routees(abs(path.hashCode) % n))) { case m@(sender, Add(actor)) ⇒ destination(sender, actor.path.name) case m@(sender, Forward(_, name)) ⇒ destination(sender, name) } } }
  • 34.
  • 35. tip #3: don't do anything stupid
  • 36. you've tried all the options, system load is fine, only 1/10 of the heap is used, but you still can start not more than 1k bots!?
  • 38. your actor is lacking of throughput?               wait before adding pools share responsibility! one fine-grained actor is enough in 99% of the cases
  • 39. 100-300 threads are serving 300 bots!?
  • 40. spawn futures, backed with standalone [bounded] pools, for blocking operations class ThirdPartyWrapper extends Actor { case F(x) => sender ! thirdPartyService.f(x) // call to a function that takes a lot of time to // complete } class ThirdPartyWrapper extends Actor { case F(x) => val _sender = sender Future(thirdPartyService.f(x)).map(_sender ! _) // ugly, but safe, and perfectly right }
  • 41. use separate dispatchers lobby-dispatcher projection-manager-dispatcher PinnedDispatcher BalancingDispatcher lobby Projection Manager desk Projection   DeskBot projection-dispatcher container-dispatcher desk-bot-dispatcher Dispatcher Dispatcher Dispatcher
  • 42. GOTCHA: Akka successfully bootstraps, even if your dispatcher is not configured, or the config is wrong   Always check the logs to make sure that dispatchers are used! [WARN][gpdev-akka.actor.default-dispatcher-1] [Dispatchers] Dispatcher [bot-system.container-dispatcher] not configured, using default-dispatcher [WARN][gpdev-bot-system.container-dispatcher-1] [PinnedDispatcherConfigurator] PinnedDispatcher [bot- system.lobby-dispatcher] not configured to use ThreadPoolExecutor, falling back to default config. [DEBUG][gpdev-akka.actor.default-dispatcher-24] [akka: //gpdev/user/poker/lobby] logged in [DEBUG][gpdev-akka.actor.default-dispatcher-14] [akka: //gpdev/user/poker/projeciton/$g/player20013] starting projection...
  • 44. how to measure?   Metrics - pushes various collected metrics to Graphite Carbon and Graphite - gather metrics, and expose them via web interface  
  • 45. object BotMetrics { 1. val loggedInCount = new Counter(Metrics.newCounter(classOf[Lobby [_]], "logged-in-count")) 3. GraphiteReporter.enable(1, TimeUnit.MINUTES, "localhost", 2003) } class Lobby extends Actor { 2. case Login(username, pass) => BotMetrics.loggedInCount += 1 } 1. add logged-in user counter 4. 2. update it 3. enable reporting to Graphite 4. build a graph in Grtaphite
  • 46. what to measure?   - mailbox size1 - throughput - time, before the message is processed (both in actor and future)2 - time to process a message - count of threads - actor pool size - heap size 1 requires implementation of a custom mailbox that can expose mailbox size 2 every message should be stuffed with a timestamp
  • 47. how to tune dispatchers?   VisualVM - thread timeline shows, if thread polls behind dispatchers are used effectively  
  • 48. don't neglect old good logging   [ERROR][05/06/2012 12:55:43.826] [gpdev-bot-system. desk-bot-dispatcher-7] [akka://gpdev/user/ poker/lobby/tournament5382577/desk109129/player2012 1] unprocessed game event: GameEvent(CHAT,None,None)