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

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

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)