SlideShare a Scribd company logo
1 of 101
Download to read offline
Designing	
  for	
  Distributed	
  Systems	
  
with	
  Reactor	
  and	
  Reactive	
  Streams
Stephane	
  Maldini	
  
@smaldini
1
WHY	
  DISTRIBUTED	
  SYSTEMS	
  ARE	
  THE	
  
NEW	
  NORMAL	
  ?
SCALING	
  MONOLITHIC	
  APPS
Payments Adult
E-­‐Learning Entertainment
Music Search
Payments Adult
E-­‐Learning Entertainment
Music Search
Payments Adult
E-­‐Learning Entertainment
Music Search
Payments Adult
E-­‐Learning Entertainment
Music Search
HOW	
  YOU	
  SHOULD	
  SCALE	
  ?
HOW	
  YOU	
  SHOULD	
  SCALE	
  ?
Enternaiment
E-­‐Learning
Payments
Adult
Music
Search
Requests
MICROSERVICES
Dependencies ?
The	
  Speed	
  Of	
  Light
I wish I acted in Star Trek Teleporting anyone ?
There’s	
  latency	
  between	
  each	
  remote	
  call
Let’s	
  use	
  asynchronous	
  processing
There’s	
  latency	
  between	
  each	
  remote	
  call
Let’s	
  use	
  asynchronous	
  processing
I	
  shall	
  not	
  block	
  incoming	
  
requests	
  to	
  keep	
  serving
There’s	
  latency	
  between	
  each	
  remote	
  call
Let’s	
  use	
  asynchronous	
  processing
I	
  shall	
  not	
  block	
  incoming	
  
requests	
  to	
  keep	
  serving
Thread	
  Executor	
  !
There’s	
  latency	
  between	
  each	
  remote	
  call
private ExecutorService threadPool = Executors.newFixedThreadPool(2);
final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() {
T result = callDatabase();
synchronized(batches) {
batches.add(result);
return result;
}
}
};
Future<T> f = threadPool.submit(t);
T result = f.get()
Vanilla	
  background-­‐processing
private ExecutorService threadPool = Executors.newFixedThreadPool(2);
final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() {
T result = callDatabase();
synchronized(batches) {
batches.add(result);
return result;
}
}
};
Future<T> f = threadPool.submit(t);
T result = f.get()
New	
  Allocation	
  By	
  Request
Vanilla	
  background-­‐processing
private ExecutorService threadPool = Executors.newFixedThreadPool(2);
final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() {
T result = callDatabase();
synchronized(batches) {
batches.add(result);
return result;
}
}
};
Future<T> f = threadPool.submit(t);
T result = f.get()
New	
  Allocation	
  By	
  Request
Queue-­‐based	
  message	
  passing
Vanilla	
  background-­‐processing
private ExecutorService threadPool = Executors.newFixedThreadPool(2);
final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() {
T result = callDatabase();
synchronized(batches) {
batches.add(result);
return result;
}
}
};
Future<T> f = threadPool.submit(t);
T result = f.get()
New	
  Allocation	
  By	
  Request
Queue-­‐based	
  message	
  passing
Vanilla	
  background-­‐processing
What	
  if	
  this	
  message	
  fails	
  ?
private ExecutorService threadPool = Executors.newFixedThreadPool(2);
final List<T> batches = new ArrayList<T>();
//…
Callable<T> t = new Callable<T>() {
public T run() {
T result = callDatabase();
synchronized(batches) {
batches.add(result);
return result;
}
}
};
Future<T> f = threadPool.submit(t);
T result = f.get()
New	
  Allocation	
  By	
  Request
Queue-­‐based	
  message	
  passing
Vanilla	
  background-­‐processing
What	
  if	
  this	
  message	
  fails	
  ?
censored
Mixing	
  latency	
  with	
  queue	
  based	
  handoff
http://ferd.ca/queues-don-t-fix-overload.html
Mixing	
  latency	
  with	
  queue	
  based	
  handoff
http://ferd.ca/queues-don-t-fix-overload.html
Mixing	
  latency	
  with	
  queue	
  based	
  handoff
http://ferd.ca/queues-don-t-fix-overload.html
Queues	
  must	
  be	
  bounded
Passing	
  message	
  /w	
  little	
  overhead
Queues	
  must	
  be	
  bounded
Passing	
  message	
  /w	
  little	
  overhead
Tolerating	
  some	
  consuming	
  rate	
  difference
Queues	
  must	
  be	
  bounded
Passing	
  message	
  /w	
  little	
  overhead
Tolerating	
  some	
  consuming	
  rate	
  difference
Reactor	
  !
Queues	
  must	
  be	
  bounded
Pre-­‐allocating	
  Slots	
  -­‐>	
  The	
  Ring	
  Buffer
Publishing
events to the right slot
dude!
Re-­‐using	
  Threads	
  too	
  :	
  Event	
  Loop
I’m an event loop, consuming
messages in the right order
//RingBufferProcessor with 32 slots by default
RingBufferProcessor<Integer> processor = 

RingBufferProcessor.create();
//Subscribe to receive events
processor.subscribe(
//Create a subscriber from a lambda/method ref
SubscriberFactory.unbounded((data, s) ->
System.out.println(data)
)
);
//Dispatch data asynchronously
int i = 0;
while(i++ < 100000) processor.onNext(i)
//Terminate the processor
processor.shutdown();
//a second subscriber to receive the same events in a
distinct thread
processor.subscribe(
SubscriberFactory.unbounded((data, s) -> {
//a slow callback returning false when not interested
in data anymore
if(!sometimeSlow(data)){
//shutdown the consumer thread
s.cancel();
}
})
);
Hold	
  on	
  !	
  The	
  guy	
  said	
  bounded	
  number	
  of	
  slots
So	
  we	
  still	
  block	
  when	
  the	
  buffer	
  is	
  full!
Hold	
  on	
  !	
  The	
  guy	
  said	
  bounded	
  number	
  of	
  slots
So	
  we	
  still	
  block	
  when	
  the	
  buffer	
  is	
  full!
…So	
  why	
  sending	
  more	
  requests
Hold	
  on	
  !	
  The	
  guy	
  said	
  bounded	
  number	
  of	
  slots
So	
  we	
  still	
  block	
  when	
  the	
  buffer	
  is	
  full!
…So	
  why	
  sending	
  more	
  requests
Reactive	
  Streams!
Hold	
  on	
  !	
  The	
  guy	
  said	
  bounded	
  number	
  of	
  slots
What	
  is	
  defined	
  in	
  Reactive	
  Streams
Async non-blocking data sequence
What	
  is	
  defined	
  in	
  Reactive	
  Streams
Async non-blocking data sequence
Minimal resources requirement
What	
  is	
  defined	
  in	
  Reactive	
  Streams
Interoperable protocol 

(Threads, Nodes…)
Async non-blocking data sequence
Minimal resources requirement
What	
  is	
  defined	
  in	
  Reactive	
  Streams
Async non-blocking flow-control
Interoperable protocol 

(Threads, Nodes…)
Async non-blocking data sequence
Minimal resources requirement
What	
  is	
  defined	
  in	
  Reactive	
  Streams
Async non-blocking flow-control
Interoperable protocol 

(Threads, Nodes…)
Async non-blocking data sequence
Minimal resources requirement
What	
  is	
  defined	
  in	
  Reactive	
  Streams
What	
  is	
  reactive	
  flow	
  control	
  ?
PUBLISHER
What	
  is	
  reactive	
  flow	
  control	
  ?
PUBLISHER
SUBSCRIBER
What	
  is	
  reactive	
  flow	
  control	
  ?
PUBLISHER
SUBSCRIBER
What	
  is	
  reactive	
  flow	
  control	
  ?
SUBSCRIPTION
PUBLISHER
SUBSCRIBER
Events
What	
  is	
  reactive	
  flow	
  control	
  ?
SUBSCRIPTION
PUBLISHER
SUBSCRIBER
Events
What	
  is	
  reactive	
  flow	
  control	
  ?
SUBSCRIPTION
PUBLISHER
SUBSCRIBER
Events
Demand
What	
  is	
  reactive	
  flow	
  control	
  ?
SUBSCRIPTION
All	
  of	
  that	
  in	
  4	
  interfaces!
And	
  there’s	
  a	
  TCK	
  to	
  verify	
  implementations
All	
  of	
  that	
  in	
  4	
  interfaces!
And	
  there’s	
  a	
  TCK	
  to	
  verify	
  implementations
No	
  More	
  Unwanted	
  Requests
All	
  of	
  that	
  in	
  4	
  interfaces!
And	
  there’s	
  a	
  TCK	
  to	
  verify	
  implementations
No	
  More	
  Unwanted	
  Requests
Need	
  to	
  propagate	
  that	
  demand	
  
upstream!
All	
  of	
  that	
  in	
  4	
  interfaces!
ccv
Doug Lea – SUNY Oswego
Some	
  Smart	
  Guys	
  Involved
RingBufferProcessor<Integer> processor = 

RingBufferProcessor.create();
//Subscribe to receive event […]
//Data access gated by a Publisher with backpressure
PublisherFactory.forEach(
sub -> {
if(sub.context().hasNext())
sub.onNext(sub.context().readInt());
else
sub.onComplete();
},
sub -> sqlContext(),
context -> context.close()
)
.subscribe(processor);
//Terminate the processor [..]
RingBufferProcessor<Integer> processor = 

RingBufferProcessor.create();
//Subscribe to receive event […]
//Data access gated by a Publisher with backpressure
PublisherFactory.forEach(
sub -> {
if(sub.context().hasNext())
sub.onNext(sub.context().readInt());
else
sub.onComplete();
},
sub -> sqlContext(),
context -> context.close()
)
.subscribe(processor);
//Terminate the processor [..]
Connect	
  processor	
  to	
  this	
  publisher	
  and	
  
start	
  requesting
RingBufferProcessor<Integer> processor = 

RingBufferProcessor.create();
//Subscribe to receive event […]
//Data access gated by a Publisher with backpressure
PublisherFactory.forEach(
sub -> {
if(sub.context().hasNext())
sub.onNext(sub.context().readInt());
else
sub.onComplete();
},
sub -> sqlContext(),
context -> context.close()
)
.subscribe(processor);
//Terminate the processor [..]
Connect	
  processor	
  to	
  this	
  publisher	
  and	
  
start	
  requesting
For	
  the	
  new	
  connected	
  
processor,	
  create	
  some	
  sql	
  
context
RingBufferProcessor<Integer> processor = 

RingBufferProcessor.create();
//Subscribe to receive event […]
//Data access gated by a Publisher with backpressure
PublisherFactory.forEach(
sub -> {
if(sub.context().hasNext())
sub.onNext(sub.context().readInt());
else
sub.onComplete();
},
sub -> sqlContext(),
context -> context.close()
)
.subscribe(processor);
//Terminate the processor [..]
Connect	
  processor	
  to	
  this	
  publisher	
  and	
  
start	
  requesting
For	
  the	
  new	
  connected	
  
processor,	
  create	
  some	
  sql	
  
context
Keep	
  invoking	
  this	
  
callback	
  until	
  there	
  is	
  no	
  more	
  
pending	
  request
What	
  about	
  combining	
  multiple	
  asynchronous	
  calls
And	
  everything	
  in	
  a	
  controlled	
  fashion
What	
  about	
  combining	
  multiple	
  asynchronous	
  calls
And	
  everything	
  in	
  a	
  controlled	
  fashion
Including	
  Errors	
  and	
  Completion	
  
What	
  about	
  combining	
  multiple	
  asynchronous	
  calls
And	
  everything	
  in	
  a	
  controlled	
  fashion
Including	
  Errors	
  and	
  Completion	
  
Reactive	
  Extensions	
  !
What	
  about	
  combining	
  multiple	
  asynchronous	
  calls
FlatMap	
  and	
  Monads..	
  Nooooo	
  Please	
  No
24
Streams.just(‘doge’).flatMap{ name ->
Streams.just(name)
.observe{ println 'so wow' }
.map{ 'much monad'}
}.consume{
assert it == 'much monad'
}
FlatMap	
  and	
  Monads..	
  Nooooo	
  Please	
  No
24
Streams.just(‘doge’).flatMap{ name ->
Streams.just(name)
.observe{ println 'so wow' }
.map{ 'much monad'}
}.consume{
assert it == 'much monad'
}
A publisher that only sends “doge” on request
FlatMap	
  and	
  Monads..	
  Nooooo	
  Please	
  No
24
Streams.just(‘doge’).flatMap{ name ->
Streams.just(name)
.observe{ println 'so wow' }
.map{ 'much monad'}
}.consume{
assert it == 'much monad'
}
A publisher that only sends “doge” on request
Sub-Stream definition
FlatMap	
  and	
  Monads..	
  Nooooo	
  Please	
  No
24
Streams.just(‘doge’).flatMap{ name ->
Streams.just(name)
.observe{ println 'so wow' }
.map{ 'much monad'}
}.consume{
assert it == 'much monad'
}
A publisher that only sends “doge” on request
Sub-Stream definition
All Sub-Streams are merged under a single sequence
Scatter	
  Gather	
  and	
  Fault	
  Tolerance
25
Streams.merge(	
  
	
  	
  userService.filteredFind(“Rick"),	
  //	
  Stream	
  of	
  User	
  
	
  	
  userService.filteredFind(“Morty")	
  //	
  Stream	
  of	
  User	
  
)	
  
.buffer()	
  //	
  Accumulate	
  all	
  results	
  in	
  a	
  List	
  
.retryWhen(	
  errors	
  -­‐>	
  //Stream	
  of	
  Errors	
  
	
  	
  errors	
  
	
  	
  .zipWith(Streams.range(1,3),	
  t	
  -­‐>	
  t.getT2())	
  	
  	
  
	
  	
  .flatMap(	
  tries	
  -­‐>	
  Streams.timer(tries)	
  )	
  
)	
  
.consume(System.out::println);
Scatter	
  Gather	
  and	
  Fault	
  Tolerance
25
Interleaved merge from 2 upstream publishers
Streams.merge(	
  
	
  	
  userService.filteredFind(“Rick"),	
  //	
  Stream	
  of	
  User	
  
	
  	
  userService.filteredFind(“Morty")	
  //	
  Stream	
  of	
  User	
  
)	
  
.buffer()	
  //	
  Accumulate	
  all	
  results	
  in	
  a	
  List	
  
.retryWhen(	
  errors	
  -­‐>	
  //Stream	
  of	
  Errors	
  
	
  	
  errors	
  
	
  	
  .zipWith(Streams.range(1,3),	
  t	
  -­‐>	
  t.getT2())	
  	
  	
  
	
  	
  .flatMap(	
  tries	
  -­‐>	
  Streams.timer(tries)	
  )	
  
)	
  
.consume(System.out::println);
Scatter	
  Gather	
  and	
  Fault	
  Tolerance
25
Interleaved merge from 2 upstream publishers
Up to 3 tries
Streams.merge(	
  
	
  	
  userService.filteredFind(“Rick"),	
  //	
  Stream	
  of	
  User	
  
	
  	
  userService.filteredFind(“Morty")	
  //	
  Stream	
  of	
  User	
  
)	
  
.buffer()	
  //	
  Accumulate	
  all	
  results	
  in	
  a	
  List	
  
.retryWhen(	
  errors	
  -­‐>	
  //Stream	
  of	
  Errors	
  
	
  	
  errors	
  
	
  	
  .zipWith(Streams.range(1,3),	
  t	
  -­‐>	
  t.getT2())	
  	
  	
  
	
  	
  .flatMap(	
  tries	
  -­‐>	
  Streams.timer(tries)	
  )	
  
)	
  
.consume(System.out::println);
Scatter	
  Gather	
  and	
  Fault	
  Tolerance
25
Interleaved merge from 2 upstream publishers
Up to 3 tries
All Sub-Streams are merged under a single sequence
Streams.merge(	
  
	
  	
  userService.filteredFind(“Rick"),	
  //	
  Stream	
  of	
  User	
  
	
  	
  userService.filteredFind(“Morty")	
  //	
  Stream	
  of	
  User	
  
)	
  
.buffer()	
  //	
  Accumulate	
  all	
  results	
  in	
  a	
  List	
  
.retryWhen(	
  errors	
  -­‐>	
  //Stream	
  of	
  Errors	
  
	
  	
  errors	
  
	
  	
  .zipWith(Streams.range(1,3),	
  t	
  -­‐>	
  t.getT2())	
  	
  	
  
	
  	
  .flatMap(	
  tries	
  -­‐>	
  Streams.timer(tries)	
  )	
  
)	
  
.consume(System.out::println);
Scatter	
  Gather	
  and	
  Fault	
  Tolerance
25
Interleaved merge from 2 upstream publishers
Up to 3 tries
All Sub-Streams are merged under a single sequence
Streams.merge(	
  
	
  	
  userService.filteredFind(“Rick"),	
  //	
  Stream	
  of	
  User	
  
	
  	
  userService.filteredFind(“Morty")	
  //	
  Stream	
  of	
  User	
  
)	
  
.buffer()	
  //	
  Accumulate	
  all	
  results	
  in	
  a	
  List	
  
.retryWhen(	
  errors	
  -­‐>	
  //Stream	
  of	
  Errors	
  
	
  	
  errors	
  
	
  	
  .zipWith(Streams.range(1,3),	
  t	
  -­‐>	
  t.getT2())	
  	
  	
  
	
  	
  .flatMap(	
  tries	
  -­‐>	
  Streams.timer(tries)	
  )	
  
)	
  
.consume(System.out::println);
Delay retry
REACTOR2™	
  =	
  	
  
REACTOR	
  +	
  REACTIVE	
  EXTENSIONS	
  +	
  REACTIVE	
  STREAMS
reactor-net
reactor-streams
reactor-bus
reactor-core
reactor-net
reactor-streams
reactor-bus
reactor-core
Event Bus
Core Dispatchers & Processors
Streams and Promises
reactor-net
reactor-streams
reactor-bus
reactor-core
Functional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
reactor-net
reactor-streams
reactor-bus
reactor-core
Functional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams
[ Clients/Server ] [TCP, UDP, HTTP]
reactor-net
reactor-streams
reactor-bus
reactor-core
Functional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams
[ Clients/Server ] [TCP, UDP, HTTP]
Fast Data
[buffer, codec]
reactor-net
reactor-streams
reactor-bus
reactor-core
Functional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams
[ Clients/Server ] [TCP, UDP, HTTP]
Fast Data
[buffer, codec]
reactor-net
reactor-streams
reactor-bus
reactor-core
Functional artifacts
(SAM components, tuples, timers)
Event Bus
Core Dispatchers & Processors
Streams and Promises
NetStreams
[ Clients/Server ] [TCP, UDP, HTTP]
Fast Data
[buffer, codec]
ASYNC	
  IO	
  ?
30
NetStreams.<String,	
  String>httpServer(spec	
  -­‐>	
  
	
  	
  	
  spec.codec(StandardCodecs.STRING_CODEC).listen(3000)	
  
).	
  
	
   ws("/",	
  channel	
  -­‐>	
  {	
  
	
   	
   System.out.println("Connected	
  a	
  websocket	
  client:	
  "	
  +	
  channel.remoteAddress());	
  
	
   	
   return	
  somePublisher.	
  
	
   	
   	
   window(1000).	
  
	
   	
   	
   flatMap(s	
  -­‐>	
  channel.writeWith(	
  s.	
  
reduce(0f,	
  (prev,	
  trade)	
  -­‐>	
  (trade.getPrice()	
  +	
  prev)	
  /	
  2).	
  
map(Object::toString)	
  )	
  
);	
  
	
   }).	
  
	
   start().	
  
	
   await();
30
NetStreams.<String,	
  String>httpServer(spec	
  -­‐>	
  
	
  	
  	
  spec.codec(StandardCodecs.STRING_CODEC).listen(3000)	
  
).	
  
	
   ws("/",	
  channel	
  -­‐>	
  {	
  
	
   	
   System.out.println("Connected	
  a	
  websocket	
  client:	
  "	
  +	
  channel.remoteAddress());	
  
	
   	
   return	
  somePublisher.	
  
	
   	
   	
   window(1000).	
  
	
   	
   	
   flatMap(s	
  -­‐>	
  channel.writeWith(	
  s.	
  
reduce(0f,	
  (prev,	
  trade)	
  -­‐>	
  (trade.getPrice()	
  +	
  prev)	
  /	
  2).	
  
map(Object::toString)	
  )	
  
);	
  
	
   }).	
  
	
   start().	
  
	
   await();
Listen	
  on	
  port	
  3000	
  
and	
  convert	
  bytes	
  into	
  String	
  inbound/
outbound
30
NetStreams.<String,	
  String>httpServer(spec	
  -­‐>	
  
	
  	
  	
  spec.codec(StandardCodecs.STRING_CODEC).listen(3000)	
  
).	
  
	
   ws("/",	
  channel	
  -­‐>	
  {	
  
	
   	
   System.out.println("Connected	
  a	
  websocket	
  client:	
  "	
  +	
  channel.remoteAddress());	
  
	
   	
   return	
  somePublisher.	
  
	
   	
   	
   window(1000).	
  
	
   	
   	
   flatMap(s	
  -­‐>	
  channel.writeWith(	
  s.	
  
reduce(0f,	
  (prev,	
  trade)	
  -­‐>	
  (trade.getPrice()	
  +	
  prev)	
  /	
  2).	
  
map(Object::toString)	
  )	
  
);	
  
	
   }).	
  
	
   start().	
  
	
   await();
Listen	
  on	
  port	
  3000	
  
and	
  convert	
  bytes	
  into	
  String	
  inbound/
outbound
Upgrade	
  clients	
  to	
  websocket	
  on	
  root	
  URI
30
NetStreams.<String,	
  String>httpServer(spec	
  -­‐>	
  
	
  	
  	
  spec.codec(StandardCodecs.STRING_CODEC).listen(3000)	
  
).	
  
	
   ws("/",	
  channel	
  -­‐>	
  {	
  
	
   	
   System.out.println("Connected	
  a	
  websocket	
  client:	
  "	
  +	
  channel.remoteAddress());	
  
	
   	
   return	
  somePublisher.	
  
	
   	
   	
   window(1000).	
  
	
   	
   	
   flatMap(s	
  -­‐>	
  channel.writeWith(	
  s.	
  
reduce(0f,	
  (prev,	
  trade)	
  -­‐>	
  (trade.getPrice()	
  +	
  prev)	
  /	
  2).	
  
map(Object::toString)	
  )	
  
);	
  
	
   }).	
  
	
   start().	
  
	
   await();
Listen	
  on	
  port	
  3000	
  
and	
  convert	
  bytes	
  into	
  String	
  inbound/
outbound
Upgrade	
  clients	
  to	
  websocket	
  on	
  root	
  URI
Flush	
  every	
  1000	
  data	
  some	
  data	
  
with	
  writeWith	
  +	
  window
30
NetStreams.<String,	
  String>httpServer(spec	
  -­‐>	
  
	
  	
  	
  spec.codec(StandardCodecs.STRING_CODEC).listen(3000)	
  
).	
  
	
   ws("/",	
  channel	
  -­‐>	
  {	
  
	
   	
   System.out.println("Connected	
  a	
  websocket	
  client:	
  "	
  +	
  channel.remoteAddress());	
  
	
   	
   return	
  somePublisher.	
  
	
   	
   	
   window(1000).	
  
	
   	
   	
   flatMap(s	
  -­‐>	
  channel.writeWith(	
  s.	
  
reduce(0f,	
  (prev,	
  trade)	
  -­‐>	
  (trade.getPrice()	
  +	
  prev)	
  /	
  2).	
  
map(Object::toString)	
  )	
  
);	
  
	
   }).	
  
	
   start().	
  
	
   await();
Listen	
  on	
  port	
  3000	
  
and	
  convert	
  bytes	
  into	
  String	
  inbound/
outbound
Upgrade	
  clients	
  to	
  websocket	
  on	
  root	
  URI
Flush	
  every	
  1000	
  data	
  some	
  data	
  
with	
  writeWith	
  +	
  windowClose	
  connection	
  when	
  
flatMap	
  completes,	
  which	
  is	
  when	
  all	
  
Windows	
  are	
  done
THE	
  STATE	
  OF	
  THE	
  ART
Now
reactive-­‐streams.1.0.0	
  
50%	
  guide	
  complete	
  :	
  http://projectreactor.io/docs/reference	
  	
  
reactor-­‐*.2.0.3.RELEASE	
  
-­‐	
  2.0.4	
  around	
  the	
  corner	
  
reactor-­‐*.2.1.0.BUILD-­‐SNAPSHOT	
  
-­‐	
  early	
  access,	
  no	
  breaking	
  changes	
  
Now
Initial	
  Reactor	
  2	
  Support	
  in	
  :	
  
Spring	
  Integration	
  4.2	
  
Spring	
  Messaging	
  4.2	
  
Spring	
  Boot	
  1.3	
  	
  
Spring	
  XD	
  1.2	
  
Grails	
  3.0
After	
  Now
Spring	
  Integration	
  DSL	
  +	
  Reactive	
  Streams	
  
Dynamic	
  Subscribers	
  on	
  Predefined	
  Channels	
  !	
  
Best	
  Tool	
  for	
  each	
  job:	
  
SI	
  for	
  integrating	
  
Reactor	
  for	
  scaling	
  up	
  too	
  fast	
  to	
  be	
  true
SI	
  Java	
  DSL	
  +	
  Reactive	
  Stream	
  Preview
@Configuration
@EnableIntegration
public static class ContextConfiguration {
@Autowired
private TaskScheduler taskScheduler;
@Bean
public Publisher<Message<String>> reactiveFlow() {
return IntegrationFlows
.from(“inputChannel”)
.split(String.class, p -> p.split(","))
.toReactiveStreamsPublisher();
}
@Bean
public Publisher<Message<Integer>> pollableReactiveFlow() {
return IntegrationFlows
.from("inputChannel")
.split(e -> e.get().getT2().setDelimiters(","))
.<String, Integer>transform(Integer::parseInt)
.channel(Channels::queue)
.toReactiveStreamsPublisher(this.taskScheduler);
}
}
After	
  Now
Reactor	
  +	
  Spring	
  Cloud	
  
•	
  Annotation	
  Driven	
  FastData	
  
•	
  Async	
  IO	
  :	
  (proxy,	
  client)	
  
•	
  Circuit	
  breaker,	
  Bus,	
  …	
  
Reactor	
  +	
  Spring	
  XD	
  
•	
  Scale	
  up	
  any	
  XD	
  pipeline	
  
•Reactive	
  Backpressure	
  in	
  XD
37
@EnableReactorModule(concurrency	
  =	
  5)	
  
public	
  class	
  PongMessageProcessor	
  implements	
  ReactiveProcessor<Message,	
  Message>	
  {	
  
	
   	
  
	
   @Override	
  
	
   public	
  void	
  accept(Stream<Message>	
  inputStream,	
  ReactiveOutput<Message>	
  output)	
  {	
  
	
   	
   output.writeOutput(	
  
	
   	
   	
   	
   inputStream	
  
	
   	
   	
   	
   	
   	
   .map(simpleMap())	
  
	
   	
   	
   	
   	
   	
   .observe(simpleMessage())	
  
	
   	
   );	
  
	
   }	
  
	
   //…	
  
}	
  
37
@EnableReactorModule(concurrency	
  =	
  5)	
  
public	
  class	
  PongMessageProcessor	
  implements	
  ReactiveProcessor<Message,	
  Message>	
  {	
  
	
   	
  
	
   @Override	
  
	
   public	
  void	
  accept(Stream<Message>	
  inputStream,	
  ReactiveOutput<Message>	
  output)	
  {	
  
	
   	
   output.writeOutput(	
  
	
   	
   	
   	
   inputStream	
  
	
   	
   	
   	
   	
   	
   .map(simpleMap())	
  
	
   	
   	
   	
   	
   	
   .observe(simpleMessage())	
  
	
   	
   );	
  
	
   }	
  
	
   //…	
  
}	
  
Split	
  input	
  XD	
  channel	
  in	
  5	
  
threads	
  !	
  With	
  a	
  blazing	
  fast	
  Processor
37
@EnableReactorModule(concurrency	
  =	
  5)	
  
public	
  class	
  PongMessageProcessor	
  implements	
  ReactiveProcessor<Message,	
  Message>	
  {	
  
	
   	
  
	
   @Override	
  
	
   public	
  void	
  accept(Stream<Message>	
  inputStream,	
  ReactiveOutput<Message>	
  output)	
  {	
  
	
   	
   output.writeOutput(	
  
	
   	
   	
   	
   inputStream	
  
	
   	
   	
   	
   	
   	
   .map(simpleMap())	
  
	
   	
   	
   	
   	
   	
   .observe(simpleMessage())	
  
	
   	
   );	
  
	
   }	
  
	
   //…	
  
}	
  
Split	
  input	
  XD	
  channel	
  in	
  5	
  
threads	
  !	
  With	
  a	
  blazing	
  fast	
  Processor
Register	
  the	
  sequence	
  to	
  write	
  on	
  the	
  output	
  
channel	
  after	
  some	
  operations
After
<3	
  Spring	
  5	
  +	
  Reactor	
  &	
  Reactive	
  Streams	
  <3
After
Reactive	
  IPC	
  for	
  the	
  JVM	
  
<3	
  RxNetty	
  +	
  reactor-­‐net	
  <3	
  
Reactor	
  2.0.3.+	
  already	
  previews	
  the	
  concept	
  
and	
  API	
  flavor…	
  
because	
  REACTOR	
  DOESN’T	
  KNOW	
  WAITING	
  
(LOL)
Future	
  ??
• RxJava	
  2.0	
  timeline	
  (2016	
  and	
  after?)	
  
• Thanks	
  Interop,	
  Reactive	
  Extensions	
  and	
  
Naming	
  conventions,	
  it	
  can	
  converge	
  with	
  
reactor-­‐streams	
  
• https://github.com/ReactiveX/RxJava/wiki/
Reactive-­‐Streams	
  
Take-­‐away
• Distributed	
  System	
  is	
  the	
  new	
  cool	
  and	
  comes	
  at	
  some	
  
cost,	
  two	
  big	
  ones	
  are	
  Latency	
  and	
  Failure	
  Tolerance	
  
• Asynchronous	
  Processing	
  and	
  Error	
  Handling	
  by	
  Design	
  
deal	
  with	
  these	
  two	
  problems	
  -­‐>	
  Reactor,	
  Reactive	
  
Extensions	
  /	
  Streams	
  
• However	
  to	
  fully	
  operate,	
  Asynchronous	
  Processing	
  
should	
  be	
  bounded	
  proactively	
  (stop-­‐read)	
  -­‐>	
  Reactive	
  
Streams
REACTIVE
Extra
Take-­‐away	
  links
• http://reactive-­‐streams.org	
  	
  
• http://projectreactor.io	
  	
  
• https://github.com/spring-­‐projects/spring-­‐integration-­‐
java-­‐dsl/pull/31	
  
• https://github.com/smaldini/spring-­‐xd/tree/refresh-­‐
reactor-­‐module/spring-­‐xd-­‐reactor/	
  	
  
• https://github.com/reactive-­‐ipc/reactive-­‐ipc-­‐jvm	
  	
  
• https://github.com/smaldini/ReactiveStreamsExamples	
  

More Related Content

What's hot

Consumer offset management in Kafka
Consumer offset management in KafkaConsumer offset management in Kafka
Consumer offset management in KafkaJoel Koshy
 
Reactive programming with Pivotal's reactor
Reactive programming with Pivotal's reactorReactive programming with Pivotal's reactor
Reactive programming with Pivotal's reactorVMware Tanzu
 
When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...
When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...
When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...confluent
 
101 mistakes FINN.no has made with Kafka (Baksida meetup)
101 mistakes FINN.no has made with Kafka (Baksida meetup)101 mistakes FINN.no has made with Kafka (Baksida meetup)
101 mistakes FINN.no has made with Kafka (Baksida meetup)Henning Spjelkavik
 
Streaming millions of Contact Center interactions in (near) real-time with Pu...
Streaming millions of Contact Center interactions in (near) real-time with Pu...Streaming millions of Contact Center interactions in (near) real-time with Pu...
Streaming millions of Contact Center interactions in (near) real-time with Pu...Frank Kelly
 
Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...
Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...
Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...confluent
 
Zoo keeper in the wild
Zoo keeper in the wildZoo keeper in the wild
Zoo keeper in the wilddatamantra
 
Practical Akka HTTP - introduction
Practical Akka HTTP - introductionPractical Akka HTTP - introduction
Practical Akka HTTP - introductionŁukasz Sowa
 
Troubleshooting Kafka's socket server: from incident to resolution
Troubleshooting Kafka's socket server: from incident to resolutionTroubleshooting Kafka's socket server: from incident to resolution
Troubleshooting Kafka's socket server: from incident to resolutionJoel Koshy
 
High-Speed Reactive Microservices - trials and tribulations
High-Speed Reactive Microservices - trials and tribulationsHigh-Speed Reactive Microservices - trials and tribulations
High-Speed Reactive Microservices - trials and tribulationsRick Hightower
 
Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...
Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...
Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...confluent
 
What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019
What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019
What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019confluent
 
Introducing Exactly Once Semantics To Apache Kafka
Introducing Exactly Once Semantics To Apache KafkaIntroducing Exactly Once Semantics To Apache Kafka
Introducing Exactly Once Semantics To Apache KafkaApurva Mehta
 
Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...
Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...
Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...Big Data Spain
 
Building a Replicated Logging System with Apache Kafka
Building a Replicated Logging System with Apache KafkaBuilding a Replicated Logging System with Apache Kafka
Building a Replicated Logging System with Apache KafkaGuozhang Wang
 
... No it's Apache Kafka!
... No it's Apache Kafka!... No it's Apache Kafka!
... No it's Apache Kafka!makker_nl
 
Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021
Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021
Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021StreamNative
 
WebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST MicroserviceWebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST MicroserviceRick Hightower
 
Exactly-once Semantics in Apache Kafka
Exactly-once Semantics in Apache KafkaExactly-once Semantics in Apache Kafka
Exactly-once Semantics in Apache Kafkaconfluent
 

What's hot (20)

Consumer offset management in Kafka
Consumer offset management in KafkaConsumer offset management in Kafka
Consumer offset management in Kafka
 
Reactive programming with Pivotal's reactor
Reactive programming with Pivotal's reactorReactive programming with Pivotal's reactor
Reactive programming with Pivotal's reactor
 
When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...
When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...
When it Absolutely, Positively, Has to be There: Reliability Guarantees in Ka...
 
101 mistakes FINN.no has made with Kafka (Baksida meetup)
101 mistakes FINN.no has made with Kafka (Baksida meetup)101 mistakes FINN.no has made with Kafka (Baksida meetup)
101 mistakes FINN.no has made with Kafka (Baksida meetup)
 
Streaming millions of Contact Center interactions in (near) real-time with Pu...
Streaming millions of Contact Center interactions in (near) real-time with Pu...Streaming millions of Contact Center interactions in (near) real-time with Pu...
Streaming millions of Contact Center interactions in (near) real-time with Pu...
 
Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...
Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...
Production Ready Kafka on Kubernetes (Devandra Tagare, Lyft) Kafka Summit SF ...
 
Zoo keeper in the wild
Zoo keeper in the wildZoo keeper in the wild
Zoo keeper in the wild
 
Practical Akka HTTP - introduction
Practical Akka HTTP - introductionPractical Akka HTTP - introduction
Practical Akka HTTP - introduction
 
Troubleshooting Kafka's socket server: from incident to resolution
Troubleshooting Kafka's socket server: from incident to resolutionTroubleshooting Kafka's socket server: from incident to resolution
Troubleshooting Kafka's socket server: from incident to resolution
 
High-Speed Reactive Microservices - trials and tribulations
High-Speed Reactive Microservices - trials and tribulationsHigh-Speed Reactive Microservices - trials and tribulations
High-Speed Reactive Microservices - trials and tribulations
 
Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...
Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...
Achieving a 50% Reduction in Cross-AZ Network Costs from Kafka (Uday Sagar Si...
 
Kafka reliability velocity 17
Kafka reliability   velocity 17Kafka reliability   velocity 17
Kafka reliability velocity 17
 
What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019
What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019
What's the time? ...and why? (Mattias Sax, Confluent) Kafka Summit SF 2019
 
Introducing Exactly Once Semantics To Apache Kafka
Introducing Exactly Once Semantics To Apache KafkaIntroducing Exactly Once Semantics To Apache Kafka
Introducing Exactly Once Semantics To Apache Kafka
 
Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...
Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...
Unified Stream Processing at Scale with Apache Samza by Jake Maes at Big Data...
 
Building a Replicated Logging System with Apache Kafka
Building a Replicated Logging System with Apache KafkaBuilding a Replicated Logging System with Apache Kafka
Building a Replicated Logging System with Apache Kafka
 
... No it's Apache Kafka!
... No it's Apache Kafka!... No it's Apache Kafka!
... No it's Apache Kafka!
 
Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021
Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021
Distributed Tests on Pulsar with Fallout - Pulsar Summit NA 2021
 
WebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST MicroserviceWebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST Microservice
 
Exactly-once Semantics in Apache Kafka
Exactly-once Semantics in Apache KafkaExactly-once Semantics in Apache Kafka
Exactly-once Semantics in Apache Kafka
 

Viewers also liked

Reactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and SpringReactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and SpringStéphane Maldini
 
Introduction to Reactive Streams and Reactor 2.5
Introduction to Reactive Streams and Reactor 2.5Introduction to Reactive Streams and Reactor 2.5
Introduction to Reactive Streams and Reactor 2.5Stéphane Maldini
 
Going Reactive
Going ReactiveGoing Reactive
Going ReactiveRob Harrop
 
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over WebsocketIntroduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocketsametmax
 
Fault Tolerance System
Fault Tolerance SystemFault Tolerance System
Fault Tolerance Systemprakashjjaya
 
2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japaneseKonrad Malawski
 
Fault tolerance in distributed systems
Fault tolerance in distributed systemsFault tolerance in distributed systems
Fault tolerance in distributed systemssumitjain2013
 

Viewers also liked (8)

Reactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and SpringReactor 3.0, a reactive foundation for java 8 and Spring
Reactor 3.0, a reactive foundation for java 8 and Spring
 
Introduction to Reactive Streams and Reactor 2.5
Introduction to Reactive Streams and Reactor 2.5Introduction to Reactive Streams and Reactor 2.5
Introduction to Reactive Streams and Reactor 2.5
 
Going Reactive
Going ReactiveGoing Reactive
Going Reactive
 
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over WebsocketIntroduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
 
Fault Tolerance System
Fault Tolerance SystemFault Tolerance System
Fault Tolerance System
 
2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese
 
Edge architecture ieee international conference on cloud engineering
Edge architecture   ieee international conference on cloud engineeringEdge architecture   ieee international conference on cloud engineering
Edge architecture ieee international conference on cloud engineering
 
Fault tolerance in distributed systems
Fault tolerance in distributed systemsFault tolerance in distributed systems
Fault tolerance in distributed systems
 

Similar to Designing for Distributed Systems with Reactor and Reactive Streams

The Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldThe Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldKonrad Malawski
 
Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014P. Taylor Goetz
 
Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...
Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...
Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...Ververica
 
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017Codemotion
 
Training Slides: 153 - Working with the CLI
Training Slides: 153 - Working with the CLITraining Slides: 153 - Working with the CLI
Training Slides: 153 - Working with the CLIContinuent
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Codemotion
 
Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''
Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''
Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''OdessaJS Conf
 
Cassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, OverviewCassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, OverviewJoshua McKenzie
 
Why async matters
Why async mattersWhy async matters
Why async matterstimbc
 
Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...
Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...
Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...Ververica
 
zenoh: zero overhead pub/sub store/query compute
zenoh: zero overhead pub/sub store/query computezenoh: zero overhead pub/sub store/query compute
zenoh: zero overhead pub/sub store/query computeAngelo Corsaro
 
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)Thomas Graf
 
Reactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServicesReactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServicesStéphane Maldini
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Baruch Sadogursky
 
Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenchesJordi Gerona
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streamsBartosz Sypytkowski
 
Reactive Streams in the Web
Reactive Streams in the WebReactive Streams in the Web
Reactive Streams in the WebFlorian Stefan
 
Networked APIs with swift
Networked APIs with swiftNetworked APIs with swift
Networked APIs with swiftTim Burks
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCKonrad Malawski
 

Similar to Designing for Distributed Systems with Reactor and Reactive Streams (20)

The Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldThe Need for Async @ ScalaWorld
The Need for Async @ ScalaWorld
 
Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014Scaling Apache Storm - Strata + Hadoop World 2014
Scaling Apache Storm - Strata + Hadoop World 2014
 
Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...
Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...
Keynote: Stephan Ewen - Stream Processing as a Foundational Paradigm and Apac...
 
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
 
Training Slides: 153 - Working with the CLI
Training Slides: 153 - Working with the CLITraining Slides: 153 - Working with the CLI
Training Slides: 153 - Working with the CLI
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
 
Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''
Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''
Alexey Orlenko ''High-performance IPC and RPC for microservices and apps''
 
Cassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, OverviewCassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, Overview
 
Why async matters
Why async mattersWhy async matters
Why async matters
 
Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...
Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...
Stephan Ewen - Stream Processing as a Foundational Paradigm and Apache Flink'...
 
zenoh: zero overhead pub/sub store/query compute
zenoh: zero overhead pub/sub store/query computezenoh: zero overhead pub/sub store/query compute
zenoh: zero overhead pub/sub store/query compute
 
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
 
Reactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServicesReactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServices
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java
 
Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenches
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
 
Reactive Streams in the Web
Reactive Streams in the WebReactive Streams in the Web
Reactive Streams in the Web
 
Networked APIs with swift
Networked APIs with swiftNetworked APIs with swift
Networked APIs with swift
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
 

More from Stéphane Maldini

The Future of Reactive Architectures
The Future of Reactive ArchitecturesThe Future of Reactive Architectures
The Future of Reactive ArchitecturesStéphane Maldini
 
What's new in Reactor Californium
What's new in Reactor CaliforniumWhat's new in Reactor Californium
What's new in Reactor CaliforniumStéphane Maldini
 
Spring boot 2.0 reactive bits (June 2018)
Spring boot 2.0 reactive bits (June 2018)Spring boot 2.0 reactive bits (June 2018)
Spring boot 2.0 reactive bits (June 2018)Stéphane Maldini
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive ProgrammingStéphane Maldini
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorStéphane Maldini
 
Reactor grails realtime web devoxx 2013
Reactor grails realtime web   devoxx 2013Reactor grails realtime web   devoxx 2013
Reactor grails realtime web devoxx 2013Stéphane Maldini
 
Groovy reactor grails realtime web devoxx 2013
Groovy reactor grails realtime web   devoxx 2013Groovy reactor grails realtime web   devoxx 2013
Groovy reactor grails realtime web devoxx 2013Stéphane Maldini
 
Reactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalReactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalStéphane Maldini
 

More from Stéphane Maldini (12)

The value of reactive
The value of reactiveThe value of reactive
The value of reactive
 
The Future of Reactive Architectures
The Future of Reactive ArchitecturesThe Future of Reactive Architectures
The Future of Reactive Architectures
 
Spring Cloud Gateway
Spring Cloud GatewaySpring Cloud Gateway
Spring Cloud Gateway
 
What's new in Reactor Californium
What's new in Reactor CaliforniumWhat's new in Reactor Californium
What's new in Reactor Californium
 
Spring boot 2.0 reactive bits (June 2018)
Spring boot 2.0 reactive bits (June 2018)Spring boot 2.0 reactive bits (June 2018)
Spring boot 2.0 reactive bits (June 2018)
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive Programming
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and Reactor
 
Reactor grails realtime web devoxx 2013
Reactor grails realtime web   devoxx 2013Reactor grails realtime web   devoxx 2013
Reactor grails realtime web devoxx 2013
 
Groovy reactor grails realtime web devoxx 2013
Groovy reactor grails realtime web   devoxx 2013Groovy reactor grails realtime web   devoxx 2013
Groovy reactor grails realtime web devoxx 2013
 
Ss2gx
Ss2gxSs2gx
Ss2gx
 
Reactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalReactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-final
 
Eventsggx
EventsggxEventsggx
Eventsggx
 

Recently uploaded

英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 

Recently uploaded (20)

英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 

Designing for Distributed Systems with Reactor and Reactive Streams

  • 1. Designing  for  Distributed  Systems   with  Reactor  and  Reactive  Streams Stephane  Maldini   @smaldini 1
  • 2. WHY  DISTRIBUTED  SYSTEMS  ARE  THE   NEW  NORMAL  ?
  • 3. SCALING  MONOLITHIC  APPS Payments Adult E-­‐Learning Entertainment Music Search Payments Adult E-­‐Learning Entertainment Music Search Payments Adult E-­‐Learning Entertainment Music Search Payments Adult E-­‐Learning Entertainment Music Search
  • 4. HOW  YOU  SHOULD  SCALE  ?
  • 5. HOW  YOU  SHOULD  SCALE  ? Enternaiment E-­‐Learning Payments Adult Music Search Requests
  • 6.
  • 9. The  Speed  Of  Light I wish I acted in Star Trek Teleporting anyone ?
  • 10. There’s  latency  between  each  remote  call
  • 11. Let’s  use  asynchronous  processing There’s  latency  between  each  remote  call
  • 12. Let’s  use  asynchronous  processing I  shall  not  block  incoming   requests  to  keep  serving There’s  latency  between  each  remote  call
  • 13. Let’s  use  asynchronous  processing I  shall  not  block  incoming   requests  to  keep  serving Thread  Executor  ! There’s  latency  between  each  remote  call
  • 14. private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>(); //… Callable<T> t = new Callable<T>() { public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } }; Future<T> f = threadPool.submit(t); T result = f.get() Vanilla  background-­‐processing
  • 15. private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>(); //… Callable<T> t = new Callable<T>() { public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } }; Future<T> f = threadPool.submit(t); T result = f.get() New  Allocation  By  Request Vanilla  background-­‐processing
  • 16. private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>(); //… Callable<T> t = new Callable<T>() { public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } }; Future<T> f = threadPool.submit(t); T result = f.get() New  Allocation  By  Request Queue-­‐based  message  passing Vanilla  background-­‐processing
  • 17. private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>(); //… Callable<T> t = new Callable<T>() { public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } }; Future<T> f = threadPool.submit(t); T result = f.get() New  Allocation  By  Request Queue-­‐based  message  passing Vanilla  background-­‐processing What  if  this  message  fails  ?
  • 18. private ExecutorService threadPool = Executors.newFixedThreadPool(2); final List<T> batches = new ArrayList<T>(); //… Callable<T> t = new Callable<T>() { public T run() { T result = callDatabase(); synchronized(batches) { batches.add(result); return result; } } }; Future<T> f = threadPool.submit(t); T result = f.get() New  Allocation  By  Request Queue-­‐based  message  passing Vanilla  background-­‐processing What  if  this  message  fails  ? censored
  • 19. Mixing  latency  with  queue  based  handoff http://ferd.ca/queues-don-t-fix-overload.html
  • 20. Mixing  latency  with  queue  based  handoff http://ferd.ca/queues-don-t-fix-overload.html
  • 21. Mixing  latency  with  queue  based  handoff http://ferd.ca/queues-don-t-fix-overload.html
  • 22. Queues  must  be  bounded
  • 23. Passing  message  /w  little  overhead Queues  must  be  bounded
  • 24. Passing  message  /w  little  overhead Tolerating  some  consuming  rate  difference Queues  must  be  bounded
  • 25. Passing  message  /w  little  overhead Tolerating  some  consuming  rate  difference Reactor  ! Queues  must  be  bounded
  • 26. Pre-­‐allocating  Slots  -­‐>  The  Ring  Buffer Publishing events to the right slot dude!
  • 27. Re-­‐using  Threads  too  :  Event  Loop I’m an event loop, consuming messages in the right order
  • 28. //RingBufferProcessor with 32 slots by default RingBufferProcessor<Integer> processor = 
 RingBufferProcessor.create(); //Subscribe to receive events processor.subscribe( //Create a subscriber from a lambda/method ref SubscriberFactory.unbounded((data, s) -> System.out.println(data) ) ); //Dispatch data asynchronously int i = 0; while(i++ < 100000) processor.onNext(i) //Terminate the processor processor.shutdown();
  • 29. //a second subscriber to receive the same events in a distinct thread processor.subscribe( SubscriberFactory.unbounded((data, s) -> { //a slow callback returning false when not interested in data anymore if(!sometimeSlow(data)){ //shutdown the consumer thread s.cancel(); } }) );
  • 30.
  • 31. Hold  on  !  The  guy  said  bounded  number  of  slots
  • 32. So  we  still  block  when  the  buffer  is  full! Hold  on  !  The  guy  said  bounded  number  of  slots
  • 33. So  we  still  block  when  the  buffer  is  full! …So  why  sending  more  requests Hold  on  !  The  guy  said  bounded  number  of  slots
  • 34. So  we  still  block  when  the  buffer  is  full! …So  why  sending  more  requests Reactive  Streams! Hold  on  !  The  guy  said  bounded  number  of  slots
  • 35. What  is  defined  in  Reactive  Streams
  • 36. Async non-blocking data sequence What  is  defined  in  Reactive  Streams
  • 37. Async non-blocking data sequence Minimal resources requirement What  is  defined  in  Reactive  Streams
  • 38. Interoperable protocol 
 (Threads, Nodes…) Async non-blocking data sequence Minimal resources requirement What  is  defined  in  Reactive  Streams
  • 39. Async non-blocking flow-control Interoperable protocol 
 (Threads, Nodes…) Async non-blocking data sequence Minimal resources requirement What  is  defined  in  Reactive  Streams
  • 40. Async non-blocking flow-control Interoperable protocol 
 (Threads, Nodes…) Async non-blocking data sequence Minimal resources requirement What  is  defined  in  Reactive  Streams
  • 41. What  is  reactive  flow  control  ?
  • 42. PUBLISHER What  is  reactive  flow  control  ?
  • 44. PUBLISHER SUBSCRIBER What  is  reactive  flow  control  ? SUBSCRIPTION
  • 45. PUBLISHER SUBSCRIBER Events What  is  reactive  flow  control  ? SUBSCRIPTION
  • 46. PUBLISHER SUBSCRIBER Events What  is  reactive  flow  control  ? SUBSCRIPTION
  • 47. PUBLISHER SUBSCRIBER Events Demand What  is  reactive  flow  control  ? SUBSCRIPTION
  • 48. All  of  that  in  4  interfaces!
  • 49. And  there’s  a  TCK  to  verify  implementations All  of  that  in  4  interfaces!
  • 50. And  there’s  a  TCK  to  verify  implementations No  More  Unwanted  Requests All  of  that  in  4  interfaces!
  • 51. And  there’s  a  TCK  to  verify  implementations No  More  Unwanted  Requests Need  to  propagate  that  demand   upstream! All  of  that  in  4  interfaces!
  • 52. ccv Doug Lea – SUNY Oswego Some  Smart  Guys  Involved
  • 53. RingBufferProcessor<Integer> processor = 
 RingBufferProcessor.create(); //Subscribe to receive event […] //Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt()); else sub.onComplete(); }, sub -> sqlContext(), context -> context.close() ) .subscribe(processor); //Terminate the processor [..]
  • 54. RingBufferProcessor<Integer> processor = 
 RingBufferProcessor.create(); //Subscribe to receive event […] //Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt()); else sub.onComplete(); }, sub -> sqlContext(), context -> context.close() ) .subscribe(processor); //Terminate the processor [..] Connect  processor  to  this  publisher  and   start  requesting
  • 55. RingBufferProcessor<Integer> processor = 
 RingBufferProcessor.create(); //Subscribe to receive event […] //Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt()); else sub.onComplete(); }, sub -> sqlContext(), context -> context.close() ) .subscribe(processor); //Terminate the processor [..] Connect  processor  to  this  publisher  and   start  requesting For  the  new  connected   processor,  create  some  sql   context
  • 56. RingBufferProcessor<Integer> processor = 
 RingBufferProcessor.create(); //Subscribe to receive event […] //Data access gated by a Publisher with backpressure PublisherFactory.forEach( sub -> { if(sub.context().hasNext()) sub.onNext(sub.context().readInt()); else sub.onComplete(); }, sub -> sqlContext(), context -> context.close() ) .subscribe(processor); //Terminate the processor [..] Connect  processor  to  this  publisher  and   start  requesting For  the  new  connected   processor,  create  some  sql   context Keep  invoking  this   callback  until  there  is  no  more   pending  request
  • 57. What  about  combining  multiple  asynchronous  calls
  • 58. And  everything  in  a  controlled  fashion What  about  combining  multiple  asynchronous  calls
  • 59. And  everything  in  a  controlled  fashion Including  Errors  and  Completion   What  about  combining  multiple  asynchronous  calls
  • 60. And  everything  in  a  controlled  fashion Including  Errors  and  Completion   Reactive  Extensions  ! What  about  combining  multiple  asynchronous  calls
  • 61. FlatMap  and  Monads..  Nooooo  Please  No 24 Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' }
  • 62. FlatMap  and  Monads..  Nooooo  Please  No 24 Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' } A publisher that only sends “doge” on request
  • 63. FlatMap  and  Monads..  Nooooo  Please  No 24 Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' } A publisher that only sends “doge” on request Sub-Stream definition
  • 64. FlatMap  and  Monads..  Nooooo  Please  No 24 Streams.just(‘doge’).flatMap{ name -> Streams.just(name) .observe{ println 'so wow' } .map{ 'much monad'} }.consume{ assert it == 'much monad' } A publisher that only sends “doge” on request Sub-Stream definition All Sub-Streams are merged under a single sequence
  • 65. Scatter  Gather  and  Fault  Tolerance 25 Streams.merge(      userService.filteredFind(“Rick"),  //  Stream  of  User      userService.filteredFind(“Morty")  //  Stream  of  User   )   .buffer()  //  Accumulate  all  results  in  a  List   .retryWhen(  errors  -­‐>  //Stream  of  Errors      errors      .zipWith(Streams.range(1,3),  t  -­‐>  t.getT2())          .flatMap(  tries  -­‐>  Streams.timer(tries)  )   )   .consume(System.out::println);
  • 66. Scatter  Gather  and  Fault  Tolerance 25 Interleaved merge from 2 upstream publishers Streams.merge(      userService.filteredFind(“Rick"),  //  Stream  of  User      userService.filteredFind(“Morty")  //  Stream  of  User   )   .buffer()  //  Accumulate  all  results  in  a  List   .retryWhen(  errors  -­‐>  //Stream  of  Errors      errors      .zipWith(Streams.range(1,3),  t  -­‐>  t.getT2())          .flatMap(  tries  -­‐>  Streams.timer(tries)  )   )   .consume(System.out::println);
  • 67. Scatter  Gather  and  Fault  Tolerance 25 Interleaved merge from 2 upstream publishers Up to 3 tries Streams.merge(      userService.filteredFind(“Rick"),  //  Stream  of  User      userService.filteredFind(“Morty")  //  Stream  of  User   )   .buffer()  //  Accumulate  all  results  in  a  List   .retryWhen(  errors  -­‐>  //Stream  of  Errors      errors      .zipWith(Streams.range(1,3),  t  -­‐>  t.getT2())          .flatMap(  tries  -­‐>  Streams.timer(tries)  )   )   .consume(System.out::println);
  • 68. Scatter  Gather  and  Fault  Tolerance 25 Interleaved merge from 2 upstream publishers Up to 3 tries All Sub-Streams are merged under a single sequence Streams.merge(      userService.filteredFind(“Rick"),  //  Stream  of  User      userService.filteredFind(“Morty")  //  Stream  of  User   )   .buffer()  //  Accumulate  all  results  in  a  List   .retryWhen(  errors  -­‐>  //Stream  of  Errors      errors      .zipWith(Streams.range(1,3),  t  -­‐>  t.getT2())          .flatMap(  tries  -­‐>  Streams.timer(tries)  )   )   .consume(System.out::println);
  • 69. Scatter  Gather  and  Fault  Tolerance 25 Interleaved merge from 2 upstream publishers Up to 3 tries All Sub-Streams are merged under a single sequence Streams.merge(      userService.filteredFind(“Rick"),  //  Stream  of  User      userService.filteredFind(“Morty")  //  Stream  of  User   )   .buffer()  //  Accumulate  all  results  in  a  List   .retryWhen(  errors  -­‐>  //Stream  of  Errors      errors      .zipWith(Streams.range(1,3),  t  -­‐>  t.getT2())          .flatMap(  tries  -­‐>  Streams.timer(tries)  )   )   .consume(System.out::println); Delay retry
  • 70. REACTOR2™  =     REACTOR  +  REACTIVE  EXTENSIONS  +  REACTIVE  STREAMS
  • 73. reactor-net reactor-streams reactor-bus reactor-core Functional artifacts (SAM components, tuples, timers) Event Bus Core Dispatchers & Processors Streams and Promises
  • 74. reactor-net reactor-streams reactor-bus reactor-core Functional artifacts (SAM components, tuples, timers) Event Bus Core Dispatchers & Processors Streams and Promises NetStreams [ Clients/Server ] [TCP, UDP, HTTP]
  • 75. reactor-net reactor-streams reactor-bus reactor-core Functional artifacts (SAM components, tuples, timers) Event Bus Core Dispatchers & Processors Streams and Promises NetStreams [ Clients/Server ] [TCP, UDP, HTTP] Fast Data [buffer, codec]
  • 76. reactor-net reactor-streams reactor-bus reactor-core Functional artifacts (SAM components, tuples, timers) Event Bus Core Dispatchers & Processors Streams and Promises NetStreams [ Clients/Server ] [TCP, UDP, HTTP] Fast Data [buffer, codec]
  • 77. reactor-net reactor-streams reactor-bus reactor-core Functional artifacts (SAM components, tuples, timers) Event Bus Core Dispatchers & Processors Streams and Promises NetStreams [ Clients/Server ] [TCP, UDP, HTTP] Fast Data [buffer, codec]
  • 79.
  • 80. 30 NetStreams.<String,  String>httpServer(spec  -­‐>        spec.codec(StandardCodecs.STRING_CODEC).listen(3000)   ).     ws("/",  channel  -­‐>  {       System.out.println("Connected  a  websocket  client:  "  +  channel.remoteAddress());       return  somePublisher.         window(1000).         flatMap(s  -­‐>  channel.writeWith(  s.   reduce(0f,  (prev,  trade)  -­‐>  (trade.getPrice()  +  prev)  /  2).   map(Object::toString)  )   );     }).     start().     await();
  • 81. 30 NetStreams.<String,  String>httpServer(spec  -­‐>        spec.codec(StandardCodecs.STRING_CODEC).listen(3000)   ).     ws("/",  channel  -­‐>  {       System.out.println("Connected  a  websocket  client:  "  +  channel.remoteAddress());       return  somePublisher.         window(1000).         flatMap(s  -­‐>  channel.writeWith(  s.   reduce(0f,  (prev,  trade)  -­‐>  (trade.getPrice()  +  prev)  /  2).   map(Object::toString)  )   );     }).     start().     await(); Listen  on  port  3000   and  convert  bytes  into  String  inbound/ outbound
  • 82. 30 NetStreams.<String,  String>httpServer(spec  -­‐>        spec.codec(StandardCodecs.STRING_CODEC).listen(3000)   ).     ws("/",  channel  -­‐>  {       System.out.println("Connected  a  websocket  client:  "  +  channel.remoteAddress());       return  somePublisher.         window(1000).         flatMap(s  -­‐>  channel.writeWith(  s.   reduce(0f,  (prev,  trade)  -­‐>  (trade.getPrice()  +  prev)  /  2).   map(Object::toString)  )   );     }).     start().     await(); Listen  on  port  3000   and  convert  bytes  into  String  inbound/ outbound Upgrade  clients  to  websocket  on  root  URI
  • 83. 30 NetStreams.<String,  String>httpServer(spec  -­‐>        spec.codec(StandardCodecs.STRING_CODEC).listen(3000)   ).     ws("/",  channel  -­‐>  {       System.out.println("Connected  a  websocket  client:  "  +  channel.remoteAddress());       return  somePublisher.         window(1000).         flatMap(s  -­‐>  channel.writeWith(  s.   reduce(0f,  (prev,  trade)  -­‐>  (trade.getPrice()  +  prev)  /  2).   map(Object::toString)  )   );     }).     start().     await(); Listen  on  port  3000   and  convert  bytes  into  String  inbound/ outbound Upgrade  clients  to  websocket  on  root  URI Flush  every  1000  data  some  data   with  writeWith  +  window
  • 84. 30 NetStreams.<String,  String>httpServer(spec  -­‐>        spec.codec(StandardCodecs.STRING_CODEC).listen(3000)   ).     ws("/",  channel  -­‐>  {       System.out.println("Connected  a  websocket  client:  "  +  channel.remoteAddress());       return  somePublisher.         window(1000).         flatMap(s  -­‐>  channel.writeWith(  s.   reduce(0f,  (prev,  trade)  -­‐>  (trade.getPrice()  +  prev)  /  2).   map(Object::toString)  )   );     }).     start().     await(); Listen  on  port  3000   and  convert  bytes  into  String  inbound/ outbound Upgrade  clients  to  websocket  on  root  URI Flush  every  1000  data  some  data   with  writeWith  +  windowClose  connection  when   flatMap  completes,  which  is  when  all   Windows  are  done
  • 85. THE  STATE  OF  THE  ART
  • 86. Now reactive-­‐streams.1.0.0   50%  guide  complete  :  http://projectreactor.io/docs/reference     reactor-­‐*.2.0.3.RELEASE   -­‐  2.0.4  around  the  corner   reactor-­‐*.2.1.0.BUILD-­‐SNAPSHOT   -­‐  early  access,  no  breaking  changes  
  • 87. Now Initial  Reactor  2  Support  in  :   Spring  Integration  4.2   Spring  Messaging  4.2   Spring  Boot  1.3     Spring  XD  1.2   Grails  3.0
  • 88. After  Now Spring  Integration  DSL  +  Reactive  Streams   Dynamic  Subscribers  on  Predefined  Channels  !   Best  Tool  for  each  job:   SI  for  integrating   Reactor  for  scaling  up  too  fast  to  be  true
  • 89. SI  Java  DSL  +  Reactive  Stream  Preview @Configuration @EnableIntegration public static class ContextConfiguration { @Autowired private TaskScheduler taskScheduler; @Bean public Publisher<Message<String>> reactiveFlow() { return IntegrationFlows .from(“inputChannel”) .split(String.class, p -> p.split(",")) .toReactiveStreamsPublisher(); } @Bean public Publisher<Message<Integer>> pollableReactiveFlow() { return IntegrationFlows .from("inputChannel") .split(e -> e.get().getT2().setDelimiters(",")) .<String, Integer>transform(Integer::parseInt) .channel(Channels::queue) .toReactiveStreamsPublisher(this.taskScheduler); } }
  • 90. After  Now Reactor  +  Spring  Cloud   •  Annotation  Driven  FastData   •  Async  IO  :  (proxy,  client)   •  Circuit  breaker,  Bus,  …   Reactor  +  Spring  XD   •  Scale  up  any  XD  pipeline   •Reactive  Backpressure  in  XD
  • 91. 37 @EnableReactorModule(concurrency  =  5)   public  class  PongMessageProcessor  implements  ReactiveProcessor<Message,  Message>  {         @Override     public  void  accept(Stream<Message>  inputStream,  ReactiveOutput<Message>  output)  {       output.writeOutput(           inputStream               .map(simpleMap())               .observe(simpleMessage())       );     }     //…   }  
  • 92. 37 @EnableReactorModule(concurrency  =  5)   public  class  PongMessageProcessor  implements  ReactiveProcessor<Message,  Message>  {         @Override     public  void  accept(Stream<Message>  inputStream,  ReactiveOutput<Message>  output)  {       output.writeOutput(           inputStream               .map(simpleMap())               .observe(simpleMessage())       );     }     //…   }   Split  input  XD  channel  in  5   threads  !  With  a  blazing  fast  Processor
  • 93. 37 @EnableReactorModule(concurrency  =  5)   public  class  PongMessageProcessor  implements  ReactiveProcessor<Message,  Message>  {         @Override     public  void  accept(Stream<Message>  inputStream,  ReactiveOutput<Message>  output)  {       output.writeOutput(           inputStream               .map(simpleMap())               .observe(simpleMessage())       );     }     //…   }   Split  input  XD  channel  in  5   threads  !  With  a  blazing  fast  Processor Register  the  sequence  to  write  on  the  output   channel  after  some  operations
  • 94. After <3  Spring  5  +  Reactor  &  Reactive  Streams  <3
  • 95. After Reactive  IPC  for  the  JVM   <3  RxNetty  +  reactor-­‐net  <3   Reactor  2.0.3.+  already  previews  the  concept   and  API  flavor…   because  REACTOR  DOESN’T  KNOW  WAITING   (LOL)
  • 96. Future  ?? • RxJava  2.0  timeline  (2016  and  after?)   • Thanks  Interop,  Reactive  Extensions  and   Naming  conventions,  it  can  converge  with   reactor-­‐streams   • https://github.com/ReactiveX/RxJava/wiki/ Reactive-­‐Streams  
  • 97. Take-­‐away • Distributed  System  is  the  new  cool  and  comes  at  some   cost,  two  big  ones  are  Latency  and  Failure  Tolerance   • Asynchronous  Processing  and  Error  Handling  by  Design   deal  with  these  two  problems  -­‐>  Reactor,  Reactive   Extensions  /  Streams   • However  to  fully  operate,  Asynchronous  Processing   should  be  bounded  proactively  (stop-­‐read)  -­‐>  Reactive   Streams
  • 98.
  • 100. Extra
  • 101. Take-­‐away  links • http://reactive-­‐streams.org     • http://projectreactor.io     • https://github.com/spring-­‐projects/spring-­‐integration-­‐ java-­‐dsl/pull/31   • https://github.com/smaldini/spring-­‐xd/tree/refresh-­‐ reactor-­‐module/spring-­‐xd-­‐reactor/     • https://github.com/reactive-­‐ipc/reactive-­‐ipc-­‐jvm     • https://github.com/smaldini/ReactiveStreamsExamples