SlideShare a Scribd company logo
Building Polyglot Systems
                      With Scalang
                      Cliff Moon
                      @moonpolysoft




Thursday, September 22, 2011
Why Scala and Erlang?


                 • Complementary sets of features.

                 • Compatible type systems.

                 • Separates concerns.




Thursday, September 22, 2011
meter
                                  meter
                                  meter   Collector          streaker
                                  meter
                                  meter
                                  meter
                                  meter
                                  meter
                                  meter
                                  meter
                                  meter   Collector           scylla
                                  meter



                                   REST   REST        REST    REST




                               Boundary Architecture
Thursday, September 22, 2011
First Revision

                 • JInterface and wrappers.

                 • Cumbersome code.

                 • Wrong level of abstraction.

                 • Not performant.



Thursday, September 22, 2011
JInterface Wrappers


                     def task(m : OtpErlangObject, mbox : OtpMbox) = m match {
                       case ETuple(EAtom("cluster"), pid : Pid, ref : Ref) =>




Thursday, September 22, 2011
Scalang


                 • Correctness of behavior.

                 • Performance.

                 • Simplicity.




Thursday, September 22, 2011
Proc      Proc       Proc


                                              Jetlang


                                             Delivery


                                              Codecs


                                              Netty


                                            NIO Sockets




                               Scalang Architecture
Thursday, September 22, 2011
Using Scalang




Thursday, September 22, 2011
Node


                     //make sure epmd is running
                     val node = Node(“scala@localhost.local”, “cookie”)




Thursday, September 22, 2011
Processes

                     class Echo(ctx : ProcessContext) extends Process(ctx) {
                        override def onMessage(msg : Any) = msg match {
                          case (pid : Pid, m : String) =>
                             pid ! m
                        }
                     }
                     val echoPid = node.spawn[Echo](“echo_server”)




Thursday, September 22, 2011
Sending Messages


                 • Send messages to a Pid.

                 • Send messages to a local registered name.

                 • Send messages to a remote registered name.




Thursday, September 22, 2011
Sending Messages - in process


                     aPid ! ‘do_something

                     ‘regname ! ‘do_another_thing

                     (‘regname, ‘erl@localhost.local) ! ‘do_something_else




Thursday, September 22, 2011
Sending Messages - outside proc


                     node.send(aPid, ‘do_something)

                     node.send(‘regname, ‘do_another_thing)

                     node.send( (‘regname, ‘erl@localhost.local), ‘do_something_else)




Thursday, September 22, 2011
Error Handling

                 • Uncaught exceptions in process code.

                 • Implemented via bi-directional links.

                 • Link breakage triggers exit notification.

                 • Links work both intra and inter - node.

                 • Not pre-emptive on the Scalang side.


Thursday, September 22, 2011
Error Handling


                     class ExitHandler(ctx : ProcessContext) extends Process(ctx) {
                       override def trapExit(from : Pid, msg : Any) {
                         log.warn(“exit notification from %s”, from)
                       }
                     }




Thursday, September 22, 2011
Type Mappings
                From Erlang     To Scala     From Scala    To Erlang
                Small Integer   Int          Byte          Small Integer
                Integer         Int          Int           Integer
                Float           Double       Long          Small Bignum
                Boolean         Boolean      Double        Float
                Atom            Symbol       Symbol        Atom
                Reference       Reference    Reference     Reference
                Port            Port         Port          Port
                Pid             Pid          Pid           Pid
                Small Tuple     Tuple        Fun           Fun
                Large Tuple     BigTuple     String        String
                String          String       List          List
                List            List         BigInteger    Large Bignum
                Binary          ByteBuffer   Array[Byte]   Binary
                Small Bignum    Long         ByteBuffer    Binary
                Large Bignum    BigInt       BitString     Bitstring
                Fun             Fun          Tuple         Tuple
                Bitstring       Bitstring    BigTuple      Tuple


Thursday, September 22, 2011
Rich Type Mappings


                 • Invoked for tagged tuples.

                 • User-supplied decode logic.

                 • Avoids performance penalty of reflective instantiation.




Thursday, September 22, 2011
Rich Type Mappings


                     (‘struct, List(      {struct, [
                       (‘key, value),       {key, Value},
                       (‘key2, value2),     {key2, Value2},
                       ... ))               ... ]}




Thursday, September 22, 2011
Rich Type Mappings

              object StructFactory extends TypeFactory {
                def createType(name : Symbol, arity : Int, reader : TermReader) : Any
                = {
                  reader.mark
                  (name, arity) match {
                    case (‘struct,2) => Some(readMap(reader))
                    case _ => reader.reset; None
                  }
                }
              }




Thursday, September 22, 2011
Rich Type Mappings


                     val node = Node(name,cookie,NodeConfig(
                                                    typeFactory = StructFactory))




Thursday, September 22, 2011
Services


                 • Initialization parameters.

                 • Built in call and cast support.

                 • Transparent interoperability with gen_server.




Thursday, September 22, 2011
Services


                 • handleCall - gen_server:call/2 - request & respose

                 • handleCast - gen_server:cast/2 - request

                 • handleInfo - Raw message received.




Thursday, September 22, 2011
Services

                     case class EchoArgs(name : Symbol)
                     class Echo(ctx : ServiceContext[EchoArgs]) extends Service(ctx) {
                       val EchoArgs(name) = ctx.args

                          override def handleCall(from : (Pid,Reference), req : Any) : Any = {
                            (name, req)
                          }
                     }




Thursday, September 22, 2011
Anonymous Processes


                     node.spawn { mbox =>
                       val msg = mbox.receive
                       // do some long running work
                       node.send(‘master, (results, mbox.self) )
                     }




Thursday, September 22, 2011
Runtime Metrics

                 • Message meters per connection.

                 • Execution histograms per process.

                 • Serialization time histograms.

                 • Message queue size gauges.

                 • Internal thread pool metrics.


Thursday, September 22, 2011
Runtime Metrics
Thursday, September 22, 2011
Performance Tuning

                 • ThreadPoolFactory - pluggable thread pool implementations.

                 • Elastic thread pools from overlock.

                 • Threads tuned to max(8, cpu_count * 2).

                 • Beware of starvation.



Thursday, September 22, 2011
Thread Pools

                 • Boss pool - Initial connection and accept handling.

                 • Worker pool - Non blocking reads and writes.

                 • Actor pool - Process callbacks.

                 • Batch Executor - Per-process execution logic.



Thursday, September 22, 2011
Thread Pools


                     val node = Node(name,cookie,NodeConfig(
                                                    poolFactory = MyThreadPools))




Thursday, September 22, 2011
Process Patterns




Thursday, September 22, 2011
Deferred Reply

                     def handleCall(from : (Pid, Reference), msg : Any) : Any = {
                       ctx.node.spawn { mbox =>
                         // long running work
                         reply(from, response)
                       }
                       ‘noreply
                     }




Thursday, September 22, 2011
State Machine


                     class Stateful(ctx : ProcessContext) extends Process(ctx) {
                       @volatile var state = ‘a
                       override def onMessage(msg : Any) = (msg, state) match {
                         case (‘event, ‘a) => ...
                       }
                     }




Thursday, September 22, 2011
Worker Pools

                     class StatelessWorker(ctx : ProcessContext) extends Process(ctx) {
                       def onMessage(msg : Any) = msg match { ... }
                     }

                     //experimental!
                     node.spawn[StatelessWorker](reentrant = true)




Thursday, September 22, 2011
Supervision Trees

                     class TaskMaster(ctx : ProcessContext) extends Process(ctx) {
                       def onMessage(msg : Any) = {
                         //distribute work to workers
                       }

                          override def handleExit(worker : Pid, reason : Any) {
                            //remove worker from pool, or restart
                          }
                     }




Thursday, September 22, 2011
Admin Endpoint


                     class Admin(ctx : ServiceContext[Args]) extends Service(ctx) {
                       def handleCall(from: (Pid,Reference), req : Any) = req match {
                         case (‘reassign, node : Symbol) =>
                           //reassign message stream to new node
                       }
                     }




Thursday, September 22, 2011
Admin Endpoint


                     ok = gen_server:call({admin, backend@data01},
                                                          {reassign, cruncher@data02}).




Thursday, September 22, 2011
Demo!




Thursday, September 22, 2011
Conclusion

                 • Wrap services in Scalang actors.

                 • Throw out your RPC codegen tools.

                 • Embrace a mesh topology.

                 • Let Erlang and Scala do the things they are good at.



Thursday, September 22, 2011
Questions?
                      https://github.com/boundary/scalang
                      https://github.com/boundary/overlock
                      Thank you.




Thursday, September 22, 2011

More Related Content

PDF
Concurrency in Python
PDF
Observer pattern with Stl, boost and qt
PDF
The dedexer disassembler
PDF
High Performance Tabular Databinding
PDF
NDK Primer (AnDevCon Boston 2014)
PDF
Intro to Kotlin
PDF
javarmi
PPTX
Kotlin Language Features - A Java comparison
Concurrency in Python
Observer pattern with Stl, boost and qt
The dedexer disassembler
High Performance Tabular Databinding
NDK Primer (AnDevCon Boston 2014)
Intro to Kotlin
javarmi
Kotlin Language Features - A Java comparison

Viewers also liked (15)

PDF
Warmbloods today article
PDF
The Art of Practice Management Dental Pearls - August 2016 - Risky Business
PDF
Bases teóricas para proyecto permacultural de ecodesarrollo
PDF
Prezume brandthink
PDF
Matthias Vallentin - Towards Interactive Network Forensics and Incident Respo...
PPTX
Pöttyös túró rudi’s success on facebook
PPTX
Relationship building and legitimacy at start up companies
PPTX
When bad publicity is good
PPSX
Avaluació compartida a l'escola
PPT
Presentazione di prova
PDF
if then is now verdienmodel 28 nov
PPSX
Presentació atletisme
PPSX
Rugby Cicle Superior
PPT
Sıvı elektrolit
Warmbloods today article
The Art of Practice Management Dental Pearls - August 2016 - Risky Business
Bases teóricas para proyecto permacultural de ecodesarrollo
Prezume brandthink
Matthias Vallentin - Towards Interactive Network Forensics and Incident Respo...
Pöttyös túró rudi’s success on facebook
Relationship building and legitimacy at start up companies
When bad publicity is good
Avaluació compartida a l'escola
Presentazione di prova
if then is now verdienmodel 28 nov
Presentació atletisme
Rugby Cicle Superior
Sıvı elektrolit
Ad

Similar to Cliff Moon - Building Polyglot Distributed Systems with Scalang, Boundary Tech Talks October 6, 2011 (20)

PDF
Martin Odersky: What's next for Scala
PDF
Erlang Message Passing Concurrency, For The Win
PDF
Erlang for video delivery
PDF
Google06
PDF
Scala google
PDF
Introduction To Erlang Final
KEY
Erlang Workshop at Dyncon 2011
PDF
Scala at HUJI PL Seminar 2008
PDF
Why Erlang? - Bar Camp Atlanta 2008
PDF
Scala @ TechMeetup Edinburgh
PPTX
All about scala
PDF
An Introduction to Scala for Java Developers
PDF
BCS SPA 2010 - An Introduction to Scala for Java Developers
PDF
Workshop Scala
PDF
The Kumofs Project and MessagePack-RPC
PDF
What's new in Scala and the Scala IDE for Eclipse for 2.8.0
KEY
Erlang bootstrap course
PDF
Clojure Interoperability
PDF
Clojure basics
KEY
Erlang/OTP for Rubyists
Martin Odersky: What's next for Scala
Erlang Message Passing Concurrency, For The Win
Erlang for video delivery
Google06
Scala google
Introduction To Erlang Final
Erlang Workshop at Dyncon 2011
Scala at HUJI PL Seminar 2008
Why Erlang? - Bar Camp Atlanta 2008
Scala @ TechMeetup Edinburgh
All about scala
An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java Developers
Workshop Scala
The Kumofs Project and MessagePack-RPC
What's new in Scala and the Scala IDE for Eclipse for 2.8.0
Erlang bootstrap course
Clojure Interoperability
Clojure basics
Erlang/OTP for Rubyists
Ad

Recently uploaded (20)

PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
sap open course for s4hana steps from ECC to s4
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
cuic standard and advanced reporting.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Empathic Computing: Creating Shared Understanding
The Rise and Fall of 3GPP – Time for a Sabbatical?
MIND Revenue Release Quarter 2 2025 Press Release
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Mobile App Security Testing_ A Comprehensive Guide.pdf
sap open course for s4hana steps from ECC to s4
“AI and Expert System Decision Support & Business Intelligence Systems”
Unlocking AI with Model Context Protocol (MCP)
cuic standard and advanced reporting.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Programs and apps: productivity, graphics, security and other tools
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Big Data Technologies - Introduction.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Spectral efficient network and resource selection model in 5G networks
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
20250228 LYD VKU AI Blended-Learning.pptx
Empathic Computing: Creating Shared Understanding

Cliff Moon - Building Polyglot Distributed Systems with Scalang, Boundary Tech Talks October 6, 2011

  • 1. Building Polyglot Systems With Scalang Cliff Moon @moonpolysoft Thursday, September 22, 2011
  • 2. Why Scala and Erlang? • Complementary sets of features. • Compatible type systems. • Separates concerns. Thursday, September 22, 2011
  • 3. meter meter meter Collector streaker meter meter meter meter meter meter meter meter Collector scylla meter REST REST REST REST Boundary Architecture Thursday, September 22, 2011
  • 4. First Revision • JInterface and wrappers. • Cumbersome code. • Wrong level of abstraction. • Not performant. Thursday, September 22, 2011
  • 5. JInterface Wrappers def task(m : OtpErlangObject, mbox : OtpMbox) = m match { case ETuple(EAtom("cluster"), pid : Pid, ref : Ref) => Thursday, September 22, 2011
  • 6. Scalang • Correctness of behavior. • Performance. • Simplicity. Thursday, September 22, 2011
  • 7. Proc Proc Proc Jetlang Delivery Codecs Netty NIO Sockets Scalang Architecture Thursday, September 22, 2011
  • 9. Node //make sure epmd is running val node = Node(“scala@localhost.local”, “cookie”) Thursday, September 22, 2011
  • 10. Processes class Echo(ctx : ProcessContext) extends Process(ctx) { override def onMessage(msg : Any) = msg match { case (pid : Pid, m : String) => pid ! m } } val echoPid = node.spawn[Echo](“echo_server”) Thursday, September 22, 2011
  • 11. Sending Messages • Send messages to a Pid. • Send messages to a local registered name. • Send messages to a remote registered name. Thursday, September 22, 2011
  • 12. Sending Messages - in process aPid ! ‘do_something ‘regname ! ‘do_another_thing (‘regname, ‘erl@localhost.local) ! ‘do_something_else Thursday, September 22, 2011
  • 13. Sending Messages - outside proc node.send(aPid, ‘do_something) node.send(‘regname, ‘do_another_thing) node.send( (‘regname, ‘erl@localhost.local), ‘do_something_else) Thursday, September 22, 2011
  • 14. Error Handling • Uncaught exceptions in process code. • Implemented via bi-directional links. • Link breakage triggers exit notification. • Links work both intra and inter - node. • Not pre-emptive on the Scalang side. Thursday, September 22, 2011
  • 15. Error Handling class ExitHandler(ctx : ProcessContext) extends Process(ctx) { override def trapExit(from : Pid, msg : Any) { log.warn(“exit notification from %s”, from) } } Thursday, September 22, 2011
  • 16. Type Mappings From Erlang To Scala From Scala To Erlang Small Integer Int Byte Small Integer Integer Int Int Integer Float Double Long Small Bignum Boolean Boolean Double Float Atom Symbol Symbol Atom Reference Reference Reference Reference Port Port Port Port Pid Pid Pid Pid Small Tuple Tuple Fun Fun Large Tuple BigTuple String String String String List List List List BigInteger Large Bignum Binary ByteBuffer Array[Byte] Binary Small Bignum Long ByteBuffer Binary Large Bignum BigInt BitString Bitstring Fun Fun Tuple Tuple Bitstring Bitstring BigTuple Tuple Thursday, September 22, 2011
  • 17. Rich Type Mappings • Invoked for tagged tuples. • User-supplied decode logic. • Avoids performance penalty of reflective instantiation. Thursday, September 22, 2011
  • 18. Rich Type Mappings (‘struct, List( {struct, [ (‘key, value), {key, Value}, (‘key2, value2), {key2, Value2}, ... )) ... ]} Thursday, September 22, 2011
  • 19. Rich Type Mappings object StructFactory extends TypeFactory { def createType(name : Symbol, arity : Int, reader : TermReader) : Any = { reader.mark (name, arity) match { case (‘struct,2) => Some(readMap(reader)) case _ => reader.reset; None } } } Thursday, September 22, 2011
  • 20. Rich Type Mappings val node = Node(name,cookie,NodeConfig( typeFactory = StructFactory)) Thursday, September 22, 2011
  • 21. Services • Initialization parameters. • Built in call and cast support. • Transparent interoperability with gen_server. Thursday, September 22, 2011
  • 22. Services • handleCall - gen_server:call/2 - request & respose • handleCast - gen_server:cast/2 - request • handleInfo - Raw message received. Thursday, September 22, 2011
  • 23. Services case class EchoArgs(name : Symbol) class Echo(ctx : ServiceContext[EchoArgs]) extends Service(ctx) { val EchoArgs(name) = ctx.args override def handleCall(from : (Pid,Reference), req : Any) : Any = { (name, req) } } Thursday, September 22, 2011
  • 24. Anonymous Processes node.spawn { mbox => val msg = mbox.receive // do some long running work node.send(‘master, (results, mbox.self) ) } Thursday, September 22, 2011
  • 25. Runtime Metrics • Message meters per connection. • Execution histograms per process. • Serialization time histograms. • Message queue size gauges. • Internal thread pool metrics. Thursday, September 22, 2011
  • 27. Performance Tuning • ThreadPoolFactory - pluggable thread pool implementations. • Elastic thread pools from overlock. • Threads tuned to max(8, cpu_count * 2). • Beware of starvation. Thursday, September 22, 2011
  • 28. Thread Pools • Boss pool - Initial connection and accept handling. • Worker pool - Non blocking reads and writes. • Actor pool - Process callbacks. • Batch Executor - Per-process execution logic. Thursday, September 22, 2011
  • 29. Thread Pools val node = Node(name,cookie,NodeConfig( poolFactory = MyThreadPools)) Thursday, September 22, 2011
  • 31. Deferred Reply def handleCall(from : (Pid, Reference), msg : Any) : Any = { ctx.node.spawn { mbox => // long running work reply(from, response) } ‘noreply } Thursday, September 22, 2011
  • 32. State Machine class Stateful(ctx : ProcessContext) extends Process(ctx) { @volatile var state = ‘a override def onMessage(msg : Any) = (msg, state) match { case (‘event, ‘a) => ... } } Thursday, September 22, 2011
  • 33. Worker Pools class StatelessWorker(ctx : ProcessContext) extends Process(ctx) { def onMessage(msg : Any) = msg match { ... } } //experimental! node.spawn[StatelessWorker](reentrant = true) Thursday, September 22, 2011
  • 34. Supervision Trees class TaskMaster(ctx : ProcessContext) extends Process(ctx) { def onMessage(msg : Any) = { //distribute work to workers } override def handleExit(worker : Pid, reason : Any) { //remove worker from pool, or restart } } Thursday, September 22, 2011
  • 35. Admin Endpoint class Admin(ctx : ServiceContext[Args]) extends Service(ctx) { def handleCall(from: (Pid,Reference), req : Any) = req match { case (‘reassign, node : Symbol) => //reassign message stream to new node } } Thursday, September 22, 2011
  • 36. Admin Endpoint ok = gen_server:call({admin, backend@data01}, {reassign, cruncher@data02}). Thursday, September 22, 2011
  • 38. Conclusion • Wrap services in Scalang actors. • Throw out your RPC codegen tools. • Embrace a mesh topology. • Let Erlang and Scala do the things they are good at. Thursday, September 22, 2011
  • 39. Questions? https://github.com/boundary/scalang https://github.com/boundary/overlock Thank you. Thursday, September 22, 2011