SlideShare uma empresa Scribd logo
1 de 40
Baixar para ler offline
Communicating
State Machines
sriram srinivasan!
sriram@malhar.net
www.malhar.net/sriram
Programming Languages Meetup, San Francisco, June 10, 2014
• Fundamental building block of computation
• Communicating State Machines model
• Synchronous and Asynchronous composition
• Hierarchical State Machines specification
• (Edward A. Lee and Pravin Varaiya, Structure and Interpretation of Signals
and Systems, LeeVaraiya.org)
State machines
• Distributed Systems
• Hardware interfaces
• Components of a memory hierarchy
• Stream producers and consumers
• Parsers and Lexers
• Filesystem and tree walker.
• Networking stack and Socket consumer
• Bidirectional communication
CSMs are Ubiquitous
C++ Boost.
struct Active : sc::simple_state< Active, StopWatch, Stopped >
{
public:
typedef sc::transition< EvReset, Active > reactions;
!
Active() : elapsedTime_( 0.0 ) {}
double ElapsedTime() const { return elapsedTime_; }
double & ElapsedTime() { return elapsedTime_; }
private:
double elapsedTime_;
}; struct Running : sc::simple_state< Running, Active >
{
public:
typedef sc::transition< EvStartStop, Stopped > reactions;
!
Running() : startTime_( std::time( 0 ) ) {}
~Running()
{
context< Active >().ElapsedTime() +=
std::difftime( std::time( 0 ), startTime_ );
}
private:
std::time_t startTime_;
};Ugh!
• Language used in TinyOS to program wireless motes
nesC
• Components with bidirectional interfaces
• Separate configuration to stitch together components
nesC Bidirectional Interfaces
interface StdControl {
command result_t init();
}
!
interface Timer {
command result_t start(char type, uint32_t interval);
command result_t stop();
event result_t fired();
}
!
interface Send {
command result_t send(TOS_Msg *msg, uint16_t length);
event result_t sendDone(TOS_Msg *msg, result_t success);
}
!
interface Device {
command result_t getData();
event result_t dataReady(uint16_t data);
}
nesC Implementation
module ChirpM {
provides interface StdControl;
uses interface Device;
uses interface Timer;
uses interface Send;
implementation {
uint16_t sensorReading;
command result_t StdControl.init() {
return call Timer.start(TIMER_REPEAT, 1000);
}
event result_t Timer.fired() {
call Device.getData();
return SUCCESS;
}
event result_t Device.dataReady(uint16_t data) {
sensorReading = data;
... send message with data in it ...
return SUCCESS;
}
}
}
StdControl
ChirpM
Timer Device Send
nesC configuration
ChirpC
configuration ChirpC {
provides interface StdControl;
}
implementation {
components 

ChirpM, 

BarometerC,
RadioAnnouncerC;
!
StdControl = ChirpM.StdControl
ChirpM.Timer -> HWTimer.Timer
ChirpM.Device -> Barometer
ChirpM.Send -> RadioAnnouncerC
}
StdControl
ChirpM
Timer Device Send
StdControl
Timer
HWTimer
Device
Barometer
Send
RadioAnnouncerC
Why aren’t more systems
structured this way?
Synchronous
Communication
Stacks as State Machines
void readMsgs( socket) {
numMsgsRead = 0
while (true) {
msg = readMsg(socket)
dispatch(msg)
log(numMsgsRead++)
}
}
void readMsg(socket) {
len := readLen(socket)
readBody(len)
}
void readLen(socket) {
byte[4] len
for i = 0 .. 4 {
len[i] = readByte(socket)
}
return len
}
• Thread of control
• Control plane = Call Chain (each frame
remembers its pc)
• Sequential flow of control defines hidden states
• Functions define major states
• Data plane = Vars local in each frame
• Blocking semantics == synchronous (lock-
step) communication
• readByte and dispatch interact with network
• Easy API; that’s why Posix and most db
calls are synchronous
State machine in Erlang
bark() ->
io:format("Dog says: BARK! BARK!~n"),
receive
pet ->
wag_tail();
_ ->
io:format("Dog is confused~n"),
bark()
after 2000 ->
bark()
end.
!
wag_tail() ->
io:format("Dog wags its tail~n"),
receive
pet ->
sit();
_ ->
io:format("Dog is confused~n"),
wag_tail()
after 30000 ->
bark()
end.
sit() ->
io:format("Dog is sitting. Gooooood boy!~n"),
receive
squirrel -> bark();
_ ->
io:format("Dog is confused~n"),
sit()
end.
• Tail-call optimization renders

change trivial
Credit: http://learnyousomeerlang.com/finite-state-machines
• Problem: Obtain leaves from a tree one at a time
Leaves from a Tree
• Problem: Obtain leaves from a tree one at a time
Leaves from a Tree
• Problem: Obtain leaves from a tree one at a time
• Two interacting state machines:
• Producer: tree, Consumer: user code that acts on the leaves.
• Pull solution: Iterators
• Convenient for clients
• for leaf in tree: 

print leaf.name
• Push solution: Functional approach
• Tree pushes data to visitors or user-defined functions
• tree.visit( myfunc )
• Ideally: Duals of each other
• In practice: Duel with each other
Leaves from a Tree
Pull Solution: Iterators
class Node:
…
def __iter__(self): return Iter(self)
!
class Iter:
def __init__(self, root):
self.nxt = root.first_leaf()
self.prev = None
def next(self):
nxt = self.nxt
if nxt: # First time entry into iterator
self.nxt = None
self.prev = nxt
return nxt
(contd).
prev = self.prev
if prev.sibling:
nxt = prev.sibling.first_leaf()
else: # explore cousins .. children of parent's siblings
parent = prev.parent
while parent:
uncle = parent.sibling
if uncle:
nxt = uncle.first_leaf()
break
else:
parent = parent.parent # continue loop
if nxt:
self.prev = nxt # for next iter
return nxt
else:
raise StopIteration
• Consumer code drives iteration
• Producer code (iterable) needs to save state between iterations
Push solution
class Node:
…
def leaves(self, callback):
if self.is_leaf():
callback(self)
else:
for c in self.children:
c.leaves(callback)
!
if self.sibling:
self.sibling.leaves(callback)
def cb(node):
print node.name
!
tree.leaves(cb)
• Consumer side:
• Callback hell
• Visitor pattern is an
abomination
• Does not have flow-control
between events
• Producer side:
• drives iteration
• stack for storing recursive
state
• Allows async consumers to
deliver events
Consumer
Producer
Push: Consumer-side trouble
exports.processJob = function(options, next) {
db.getUser(options.userId, function(err, user) {
if (error) return next(err);
db.updateAccount(user.accountId, options.total, function(err) {
if (err) return next(err);
http.post(options.url, function(err) {
if (err) return next(err);
next();
});
}); 
});
};
def sameFringe(treeA, treeB):
itreeA = iter(treeA)
itreeB = iter(treeB)
while 1:
nodeA = itreeA.next()
nodeB = itreeB.next()
if node A .name != nodeB.name: return False
….
Callback Hell
!
Sequential chain of 

events verbose to 

express
!
Inversion of control
Concurrent Traversals 

trivial in Pull approach
Generators/Coroutines
Generators: Concurrent Stacks
o = odds()
!
print o.next()
print o.next()
print o.next()
!
# Print infinite stream
for n in odds() :
print n
def odds():
i = 1
while True:
yield i
i += 2
for leaf in tree.leaves():
print leaf.name
class Tree:
def leaves(self):
if self.is_leaf():
yield self
else:
for c in self.children:
for leaf in c.leaves():
yield leaf
• Generators/Coroutines are simply a compiler transformation of
threaded to event-driven code on same kernel thread
• Flow of control alternates between consumer and producer
• Cheap user-level tasks with explicit cooperative scheduling
• Scheduler calls next()
• Task calls yield() whenever necessary
• Wrapped in an abstraction called Fiber
• Ruby: Fiber.yield, Javascript: function*, yield/yield*
• Symmetric vs Asymmetric coroutines
• Lazy streams — Infinite streams on demand
Generators
Asynchrony and Multiprocessing
• All threads have the same fixed size set at creation time:
usually set to worst case 



• Kernel Thread context switching is expensive (in μs)
• Preemption at any time ==> Save all registers: 16 general purpose registers, PC, SP,
segment registers, 16 XMM registers, FP coprocessor state, X AVX registers, all MSRs
• TLB flushes, cache invalidation, crossing kernel protection boundary
• Even cooperative yields are expensive.
• A kernel thread is a precious resource. Can’t block it.
• No, not for IO-bound code, says Paul Tyma
Why can’t we just use Kernel Threads?
> ulimit –s
8192
Threads vs Events Debate
• But horrible user-programming model
• libuv, libasync, EventMachine (Ruby), netty (Java)
• User-code must not block, not call other I/O
operations
Event-driven I/O is faster
Netty inversion of control
io.netty.handler.codec.DecoderException: java.lang.RuntimeException: No packet with id 78
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:263)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:131)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:173)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.handler.codec.ByteToMessageDecoder.handlerRemoved(ByteToMessageDecoder.java:109)
at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:524)
at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved(DefaultChannelPipeline.java:518)
at io.netty.channel.DefaultChannelPipeline.remove0(DefaultChannelPipeline.java:348)
at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:319)
at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:296)
at org.spigotmc.netty.LegacyDecoder.decode(LegacyDecoder.java:38)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:232)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:131)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.handler.timeout.ReadTimeoutHandler.channelRead(ReadTimeoutHandler.java:149)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:100)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.RuntimeException: No packet with id 78
at org.spigotmc.netty.Protocol$ProtocolDirection.createPacket(Protocol.java:272)
at org.spigotmc.netty.PacketDecoder.decode(PacketDecoder.java:44)
Let’s compromise. Let’s both be
unhappy.
• All I/O handled by special I/O event loop in separate
thread
• Can’t do I/O in callback
• Cannot block
• Handed off to a task on a separate thread pool
• Task cannot block there either; limited threads in thread pool
• Hand-rolled continuations
Current mainstream
Netty
public	
  class	
  WriteTimeOutHandler	
  extends	
  ChannelOutboundHandlerAdapter	
  {	
  
	
  	
  @Override	
  
	
  	
  public	
  void	
  write(ChannelHandlerContext	
  ctx,	
  Object	
  msg,	
  ChannelPromise	
  promise)	
  
{	
  
	
  	
  	
  	
  ctx.write(msg,	
  promise);	
  
!
	
  	
  	
  	
  if	
  (!promise.isDone()	
  {	
  
	
  	
  	
  	
  	
  	
  ctx.executor().schedule(new	
  WriteTimeoutTask(promise),	
  30,	
  TimeUnit.SECONDS);	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
}	
  
Ugh.
Functional Reactive Programming
getDataFromNetwork()
.skip(10)
.take(5)
.map({ s -> return s + " transformed" })
.subscribe({ println "onNext => " + it })
• Reactive extensions .NET, RxJava, Scala
• Asynchronous stream. A chain of transformers
ending with a callback.
• Effectively with the same kinds of restrictions:
• No blocking, worry about thread context (“can I write to a socket”)
• Pretty sequential code.
• Millions of Threads.
• Block when we want to.
• Receive and Send to other SMs anywhere.
• Receive from multiple sources
• Speed and lightness of Event-driven solutions
Can we have it all?
• kilim.malhar.net
• Bytecode transformer for coroutines/generators and
lightweight tasks
• s/Thread/Task/
• s/run()/execute() throws Pausable/
• All functions that may block annotated as “throws Pausable”
• Use typed mailboxes to communicate
• Bytecode transformation of Java code.
• Offline or at class load time
Ta da! Kilim
Kilim Performance vs. Threads
Kilim Server Performance vs. Jetty
• Lightweight threads — C layout, small dynamic stacks
• Multiplex on channel I/O — CSP’s alt operator.
• Fast context switching — three registers to save and restore
(PC, SP and DX)
• Syntactic lightness
• Language and idioms fit in my L1 cache
• Closures, Duck-typing
• 0-sized channels == true synchronous lock-step
• What I want: Some aspects of Swift/Rust!
What I like about Go
Go
package main
func main() {
ch := make(chan int)
!
go func() { // producer
i := 1
for {
ch <– i
i += 2
}
}()
!
for { // consumer
println(<–ch)
}
}
Go
func main() {
// Listen and accept loop
tcpaddr, err := net.ResolveTCPAddr("tcp", "localhost:9999")
check(err)
tcp_acceptor, err := net.ListenTCP("tcp", tcpaddr)
check(err)
fmt.Println("Listening on ", tcp_acceptor.Addr())
!
for true {
tcp_conn, err := tcp_acceptor.AcceptTCP()
check(err)
go serve(tcp_conn)
}
}
func serve(conn *net.TCPConn) {
for true {
dec := gob.NewDecoder(conn)
//var msg Msg
var data string
//err := dec.Decode(&msg)
err := dec.Decode(&data)
check(err)
println("Server: Rcvd ", data)
//println("Server: Rcvd ", msg.Data, "from", msg.From)
….
}
• Compiler transformation of ‘go’ blocks into event-
driven code
• All blocking calls must be made directly inside a go
block
• Channel receives and sends cannot be made in a called function
• In general, all approaches relying only on compiler
transformations leak abstractions. Need Go/Erlang
like deep runtime support
Clojure core.async
• Threaded style is easy to write and understand
• Actors are not internally concurrent; no internal data races.
• Undesirable combination: Aliasing + Mutability
• Either aliased+immutable — clojure approach
• Unaliased+mutable — KIlim, Rust, Go approach.
• Isolate actor state, and exchange messages. Rust’s linear type system is wonderful.
• Go mantra: Share by communicate, not communicate by sharing
• No more threads vs. events debates. You can have it all
• Erlang, Go, Rust, Kilim for Java, Akka for Scala, F#
Takeaways

Mais conteúdo relacionado

Mais procurados

Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13Jay Coskey
 
O caml2014 leroy-slides
O caml2014 leroy-slidesO caml2014 leroy-slides
O caml2014 leroy-slidesOCaml
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Lecture02 class -_templatev2
Lecture02 class -_templatev2Lecture02 class -_templatev2
Lecture02 class -_templatev2Hariz Mustafa
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingMario Fusco
 
Lecture11 standard template-library
Lecture11 standard template-libraryLecture11 standard template-library
Lecture11 standard template-libraryHariz Mustafa
 
julia-Latest Programming language
julia-Latest Programming  languagejulia-Latest Programming  language
julia-Latest Programming languageNithya Prakasan
 
Python Closures Explained | What are Closures in Python | Python Closures
Python Closures Explained | What are Closures in Python | Python ClosuresPython Closures Explained | What are Closures in Python | Python Closures
Python Closures Explained | What are Closures in Python | Python ClosuresIntellipaat
 
Clojure, Plain and Simple
Clojure, Plain and SimpleClojure, Plain and Simple
Clojure, Plain and SimpleBen Mabey
 
Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Sameer Rathoud
 
Iterarators and generators in python
Iterarators and generators in pythonIterarators and generators in python
Iterarators and generators in pythonSarfaraz Ghanta
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John StevensonJAX London
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++Tech_MX
 

Mais procurados (20)

Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Advance python
Advance pythonAdvance python
Advance python
 
O caml2014 leroy-slides
O caml2014 leroy-slidesO caml2014 leroy-slides
O caml2014 leroy-slides
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Lecture02 class -_templatev2
Lecture02 class -_templatev2Lecture02 class -_templatev2
Lecture02 class -_templatev2
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
 
Lecture11 standard template-library
Lecture11 standard template-libraryLecture11 standard template-library
Lecture11 standard template-library
 
julia-Latest Programming language
julia-Latest Programming  languagejulia-Latest Programming  language
julia-Latest Programming language
 
Scala - core features
Scala - core featuresScala - core features
Scala - core features
 
Python in 90 minutes
Python in 90 minutesPython in 90 minutes
Python in 90 minutes
 
Python Closures Explained | What are Closures in Python | Python Closures
Python Closures Explained | What are Closures in Python | Python ClosuresPython Closures Explained | What are Closures in Python | Python Closures
Python Closures Explained | What are Closures in Python | Python Closures
 
Clojure, Plain and Simple
Clojure, Plain and SimpleClojure, Plain and Simple
Clojure, Plain and Simple
 
Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())
 
Iterarators and generators in python
Iterarators and generators in pythonIterarators and generators in python
Iterarators and generators in python
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
 
Ajaxworld
AjaxworldAjaxworld
Ajaxworld
 
Operator overload rr
Operator overload  rrOperator overload  rr
Operator overload rr
 
Linux Internals - Part III
Linux Internals - Part IIILinux Internals - Part III
Linux Internals - Part III
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++
 

Semelhante a Communicating State Machines

Process and Threads in Linux - PPT
Process and Threads in Linux - PPTProcess and Threads in Linux - PPT
Process and Threads in Linux - PPTQUONTRASOLUTIONS
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
Sedna XML Database: Executor Internals
Sedna XML Database: Executor InternalsSedna XML Database: Executor Internals
Sedna XML Database: Executor InternalsIvan Shcheklein
 
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxNET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxpetabridge
 
Getting started with Spark & Cassandra by Jon Haddad of Datastax
Getting started with Spark & Cassandra by Jon Haddad of DatastaxGetting started with Spark & Cassandra by Jon Haddad of Datastax
Getting started with Spark & Cassandra by Jon Haddad of DatastaxData Con LA
 
Functional Programming and Composing Actors
Functional Programming and Composing ActorsFunctional Programming and Composing Actors
Functional Programming and Composing Actorslegendofklang
 
Clojure ♥ cassandra
Clojure ♥ cassandra Clojure ♥ cassandra
Clojure ♥ cassandra Max Penet
 
Threads and multi threading
Threads and multi threadingThreads and multi threading
Threads and multi threadingAntonio Cesarano
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring frameworkSunghyouk Bae
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrencyAlex Navis
 
SparkSQL: A Compiler from Queries to RDDs
SparkSQL: A Compiler from Queries to RDDsSparkSQL: A Compiler from Queries to RDDs
SparkSQL: A Compiler from Queries to RDDsDatabricks
 
Speed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudSpeed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudRevolution Analytics
 
Replication MongoDB Days 2013
Replication MongoDB Days 2013Replication MongoDB Days 2013
Replication MongoDB Days 2013Randall Hunt
 
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...apidays
 
Performance analysis and troubleshooting using DTrace
Performance analysis and troubleshooting using DTracePerformance analysis and troubleshooting using DTrace
Performance analysis and troubleshooting using DTraceGraeme Jenkinson
 
.Net Garbage Collector 101
.Net Garbage Collector 101.Net Garbage Collector 101
.Net Garbage Collector 101Woody Pewitt
 
Scaling web applications with cassandra presentation
Scaling web applications with cassandra presentationScaling web applications with cassandra presentation
Scaling web applications with cassandra presentationMurat Çakal
 

Semelhante a Communicating State Machines (20)

Process and Threads in Linux - PPT
Process and Threads in Linux - PPTProcess and Threads in Linux - PPT
Process and Threads in Linux - PPT
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Sedna XML Database: Executor Internals
Sedna XML Database: Executor InternalsSedna XML Database: Executor Internals
Sedna XML Database: Executor Internals
 
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxNET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptx
 
Concurrency
ConcurrencyConcurrency
Concurrency
 
Getting started with Spark & Cassandra by Jon Haddad of Datastax
Getting started with Spark & Cassandra by Jon Haddad of DatastaxGetting started with Spark & Cassandra by Jon Haddad of Datastax
Getting started with Spark & Cassandra by Jon Haddad of Datastax
 
Functional Programming and Composing Actors
Functional Programming and Composing ActorsFunctional Programming and Composing Actors
Functional Programming and Composing Actors
 
Clojure ♥ cassandra
Clojure ♥ cassandra Clojure ♥ cassandra
Clojure ♥ cassandra
 
Threads and multi threading
Threads and multi threadingThreads and multi threading
Threads and multi threading
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
 
SparkSQL: A Compiler from Queries to RDDs
SparkSQL: A Compiler from Queries to RDDsSparkSQL: A Compiler from Queries to RDDs
SparkSQL: A Compiler from Queries to RDDs
 
bluespec talk
bluespec talkbluespec talk
bluespec talk
 
Speed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudSpeed up R with parallel programming in the Cloud
Speed up R with parallel programming in the Cloud
 
Replication MongoDB Days 2013
Replication MongoDB Days 2013Replication MongoDB Days 2013
Replication MongoDB Days 2013
 
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
 
Performance analysis and troubleshooting using DTrace
Performance analysis and troubleshooting using DTracePerformance analysis and troubleshooting using DTrace
Performance analysis and troubleshooting using DTrace
 
Dynomite Nosql
Dynomite NosqlDynomite Nosql
Dynomite Nosql
 
.Net Garbage Collector 101
.Net Garbage Collector 101.Net Garbage Collector 101
.Net Garbage Collector 101
 
Scaling web applications with cassandra presentation
Scaling web applications with cassandra presentationScaling web applications with cassandra presentation
Scaling web applications with cassandra presentation
 

Último

%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456KiaraTiradoMicha
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 

Último (20)

%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 

Communicating State Machines

  • 2. • Fundamental building block of computation • Communicating State Machines model • Synchronous and Asynchronous composition • Hierarchical State Machines specification • (Edward A. Lee and Pravin Varaiya, Structure and Interpretation of Signals and Systems, LeeVaraiya.org) State machines
  • 3. • Distributed Systems • Hardware interfaces • Components of a memory hierarchy • Stream producers and consumers • Parsers and Lexers • Filesystem and tree walker. • Networking stack and Socket consumer • Bidirectional communication CSMs are Ubiquitous
  • 4. C++ Boost. struct Active : sc::simple_state< Active, StopWatch, Stopped > { public: typedef sc::transition< EvReset, Active > reactions; ! Active() : elapsedTime_( 0.0 ) {} double ElapsedTime() const { return elapsedTime_; } double & ElapsedTime() { return elapsedTime_; } private: double elapsedTime_; }; struct Running : sc::simple_state< Running, Active > { public: typedef sc::transition< EvStartStop, Stopped > reactions; ! Running() : startTime_( std::time( 0 ) ) {} ~Running() { context< Active >().ElapsedTime() += std::difftime( std::time( 0 ), startTime_ ); } private: std::time_t startTime_; };Ugh!
  • 5. • Language used in TinyOS to program wireless motes nesC • Components with bidirectional interfaces • Separate configuration to stitch together components
  • 6. nesC Bidirectional Interfaces interface StdControl { command result_t init(); } ! interface Timer { command result_t start(char type, uint32_t interval); command result_t stop(); event result_t fired(); } ! interface Send { command result_t send(TOS_Msg *msg, uint16_t length); event result_t sendDone(TOS_Msg *msg, result_t success); } ! interface Device { command result_t getData(); event result_t dataReady(uint16_t data); }
  • 7. nesC Implementation module ChirpM { provides interface StdControl; uses interface Device; uses interface Timer; uses interface Send; implementation { uint16_t sensorReading; command result_t StdControl.init() { return call Timer.start(TIMER_REPEAT, 1000); } event result_t Timer.fired() { call Device.getData(); return SUCCESS; } event result_t Device.dataReady(uint16_t data) { sensorReading = data; ... send message with data in it ... return SUCCESS; } } } StdControl ChirpM Timer Device Send
  • 8. nesC configuration ChirpC configuration ChirpC { provides interface StdControl; } implementation { components 
 ChirpM, 
 BarometerC, RadioAnnouncerC; ! StdControl = ChirpM.StdControl ChirpM.Timer -> HWTimer.Timer ChirpM.Device -> Barometer ChirpM.Send -> RadioAnnouncerC } StdControl ChirpM Timer Device Send StdControl Timer HWTimer Device Barometer Send RadioAnnouncerC
  • 9. Why aren’t more systems structured this way?
  • 11. Stacks as State Machines void readMsgs( socket) { numMsgsRead = 0 while (true) { msg = readMsg(socket) dispatch(msg) log(numMsgsRead++) } } void readMsg(socket) { len := readLen(socket) readBody(len) } void readLen(socket) { byte[4] len for i = 0 .. 4 { len[i] = readByte(socket) } return len } • Thread of control • Control plane = Call Chain (each frame remembers its pc) • Sequential flow of control defines hidden states • Functions define major states • Data plane = Vars local in each frame • Blocking semantics == synchronous (lock- step) communication • readByte and dispatch interact with network • Easy API; that’s why Posix and most db calls are synchronous
  • 12. State machine in Erlang bark() -> io:format("Dog says: BARK! BARK!~n"), receive pet -> wag_tail(); _ -> io:format("Dog is confused~n"), bark() after 2000 -> bark() end. ! wag_tail() -> io:format("Dog wags its tail~n"), receive pet -> sit(); _ -> io:format("Dog is confused~n"), wag_tail() after 30000 -> bark() end. sit() -> io:format("Dog is sitting. Gooooood boy!~n"), receive squirrel -> bark(); _ -> io:format("Dog is confused~n"), sit() end. • Tail-call optimization renders
 change trivial Credit: http://learnyousomeerlang.com/finite-state-machines
  • 13. • Problem: Obtain leaves from a tree one at a time Leaves from a Tree
  • 14. • Problem: Obtain leaves from a tree one at a time Leaves from a Tree
  • 15. • Problem: Obtain leaves from a tree one at a time • Two interacting state machines: • Producer: tree, Consumer: user code that acts on the leaves. • Pull solution: Iterators • Convenient for clients • for leaf in tree: 
 print leaf.name • Push solution: Functional approach • Tree pushes data to visitors or user-defined functions • tree.visit( myfunc ) • Ideally: Duals of each other • In practice: Duel with each other Leaves from a Tree
  • 16. Pull Solution: Iterators class Node: … def __iter__(self): return Iter(self) ! class Iter: def __init__(self, root): self.nxt = root.first_leaf() self.prev = None def next(self): nxt = self.nxt if nxt: # First time entry into iterator self.nxt = None self.prev = nxt return nxt (contd). prev = self.prev if prev.sibling: nxt = prev.sibling.first_leaf() else: # explore cousins .. children of parent's siblings parent = prev.parent while parent: uncle = parent.sibling if uncle: nxt = uncle.first_leaf() break else: parent = parent.parent # continue loop if nxt: self.prev = nxt # for next iter return nxt else: raise StopIteration • Consumer code drives iteration • Producer code (iterable) needs to save state between iterations
  • 17. Push solution class Node: … def leaves(self, callback): if self.is_leaf(): callback(self) else: for c in self.children: c.leaves(callback) ! if self.sibling: self.sibling.leaves(callback) def cb(node): print node.name ! tree.leaves(cb) • Consumer side: • Callback hell • Visitor pattern is an abomination • Does not have flow-control between events • Producer side: • drives iteration • stack for storing recursive state • Allows async consumers to deliver events Consumer Producer
  • 18. Push: Consumer-side trouble exports.processJob = function(options, next) { db.getUser(options.userId, function(err, user) { if (error) return next(err); db.updateAccount(user.accountId, options.total, function(err) { if (err) return next(err); http.post(options.url, function(err) { if (err) return next(err); next(); }); });  }); }; def sameFringe(treeA, treeB): itreeA = iter(treeA) itreeB = iter(treeB) while 1: nodeA = itreeA.next() nodeB = itreeB.next() if node A .name != nodeB.name: return False …. Callback Hell ! Sequential chain of 
 events verbose to 
 express ! Inversion of control Concurrent Traversals 
 trivial in Pull approach
  • 20. Generators: Concurrent Stacks o = odds() ! print o.next() print o.next() print o.next() ! # Print infinite stream for n in odds() : print n def odds(): i = 1 while True: yield i i += 2 for leaf in tree.leaves(): print leaf.name class Tree: def leaves(self): if self.is_leaf(): yield self else: for c in self.children: for leaf in c.leaves(): yield leaf
  • 21. • Generators/Coroutines are simply a compiler transformation of threaded to event-driven code on same kernel thread • Flow of control alternates between consumer and producer • Cheap user-level tasks with explicit cooperative scheduling • Scheduler calls next() • Task calls yield() whenever necessary • Wrapped in an abstraction called Fiber • Ruby: Fiber.yield, Javascript: function*, yield/yield* • Symmetric vs Asymmetric coroutines • Lazy streams — Infinite streams on demand Generators
  • 23. • All threads have the same fixed size set at creation time: usually set to worst case 
 
 • Kernel Thread context switching is expensive (in μs) • Preemption at any time ==> Save all registers: 16 general purpose registers, PC, SP, segment registers, 16 XMM registers, FP coprocessor state, X AVX registers, all MSRs • TLB flushes, cache invalidation, crossing kernel protection boundary • Even cooperative yields are expensive. • A kernel thread is a precious resource. Can’t block it. • No, not for IO-bound code, says Paul Tyma Why can’t we just use Kernel Threads? > ulimit –s 8192
  • 25. • But horrible user-programming model • libuv, libasync, EventMachine (Ruby), netty (Java) • User-code must not block, not call other I/O operations Event-driven I/O is faster
  • 26. Netty inversion of control io.netty.handler.codec.DecoderException: java.lang.RuntimeException: No packet with id 78 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:263) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:131) at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:173) at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) at io.netty.handler.codec.ByteToMessageDecoder.handlerRemoved(ByteToMessageDecoder.java:109) at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:524) at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved(DefaultChannelPipeline.java:518) at io.netty.channel.DefaultChannelPipeline.remove0(DefaultChannelPipeline.java:348) at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:319) at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:296) at org.spigotmc.netty.LegacyDecoder.decode(LegacyDecoder.java:38) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:232) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:131) at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) at io.netty.handler.timeout.ReadTimeoutHandler.channelRead(ReadTimeoutHandler.java:149) at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:100) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341) at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) at java.lang.Thread.run(Thread.java:744) Caused by: java.lang.RuntimeException: No packet with id 78 at org.spigotmc.netty.Protocol$ProtocolDirection.createPacket(Protocol.java:272) at org.spigotmc.netty.PacketDecoder.decode(PacketDecoder.java:44)
  • 27. Let’s compromise. Let’s both be unhappy.
  • 28. • All I/O handled by special I/O event loop in separate thread • Can’t do I/O in callback • Cannot block • Handed off to a task on a separate thread pool • Task cannot block there either; limited threads in thread pool • Hand-rolled continuations Current mainstream
  • 29. Netty public  class  WriteTimeOutHandler  extends  ChannelOutboundHandlerAdapter  {      @Override      public  void  write(ChannelHandlerContext  ctx,  Object  msg,  ChannelPromise  promise)   {          ctx.write(msg,  promise);   !        if  (!promise.isDone()  {              ctx.executor().schedule(new  WriteTimeoutTask(promise),  30,  TimeUnit.SECONDS);          }      }   }   Ugh.
  • 30. Functional Reactive Programming getDataFromNetwork() .skip(10) .take(5) .map({ s -> return s + " transformed" }) .subscribe({ println "onNext => " + it }) • Reactive extensions .NET, RxJava, Scala • Asynchronous stream. A chain of transformers ending with a callback. • Effectively with the same kinds of restrictions: • No blocking, worry about thread context (“can I write to a socket”)
  • 31. • Pretty sequential code. • Millions of Threads. • Block when we want to. • Receive and Send to other SMs anywhere. • Receive from multiple sources • Speed and lightness of Event-driven solutions Can we have it all?
  • 32. • kilim.malhar.net • Bytecode transformer for coroutines/generators and lightweight tasks • s/Thread/Task/ • s/run()/execute() throws Pausable/ • All functions that may block annotated as “throws Pausable” • Use typed mailboxes to communicate • Bytecode transformation of Java code. • Offline or at class load time Ta da! Kilim
  • 33.
  • 36. • Lightweight threads — C layout, small dynamic stacks • Multiplex on channel I/O — CSP’s alt operator. • Fast context switching — three registers to save and restore (PC, SP and DX) • Syntactic lightness • Language and idioms fit in my L1 cache • Closures, Duck-typing • 0-sized channels == true synchronous lock-step • What I want: Some aspects of Swift/Rust! What I like about Go
  • 37. Go package main func main() { ch := make(chan int) ! go func() { // producer i := 1 for { ch <– i i += 2 } }() ! for { // consumer println(<–ch) } }
  • 38. Go func main() { // Listen and accept loop tcpaddr, err := net.ResolveTCPAddr("tcp", "localhost:9999") check(err) tcp_acceptor, err := net.ListenTCP("tcp", tcpaddr) check(err) fmt.Println("Listening on ", tcp_acceptor.Addr()) ! for true { tcp_conn, err := tcp_acceptor.AcceptTCP() check(err) go serve(tcp_conn) } } func serve(conn *net.TCPConn) { for true { dec := gob.NewDecoder(conn) //var msg Msg var data string //err := dec.Decode(&msg) err := dec.Decode(&data) check(err) println("Server: Rcvd ", data) //println("Server: Rcvd ", msg.Data, "from", msg.From) …. }
  • 39. • Compiler transformation of ‘go’ blocks into event- driven code • All blocking calls must be made directly inside a go block • Channel receives and sends cannot be made in a called function • In general, all approaches relying only on compiler transformations leak abstractions. Need Go/Erlang like deep runtime support Clojure core.async
  • 40. • Threaded style is easy to write and understand • Actors are not internally concurrent; no internal data races. • Undesirable combination: Aliasing + Mutability • Either aliased+immutable — clojure approach • Unaliased+mutable — KIlim, Rust, Go approach. • Isolate actor state, and exchange messages. Rust’s linear type system is wonderful. • Go mantra: Share by communicate, not communicate by sharing • No more threads vs. events debates. You can have it all • Erlang, Go, Rust, Kilim for Java, Akka for Scala, F# Takeaways