SlideShare a Scribd company logo
1 of 90
Download to read offline
Groovy, Reactor, Grails 

& the realtime web
Guillaume Laforge 

@glaforge !

Stéphane Maldini

@smaldini !
Stéphane
Maldini
Consultant and Reactor committer
at
.
!

@smaldini
1
t
r
a
P

Reactor
Reactor — Housekeeping
!

• Tweet questions during the presentation	

– @ProjectReactor
!

• Stop us anywhere if you have a question	

– There are no stupid questions, only stupid answers!

@glaforge — @smaldini / #DV13-rtweb

!4
Reactor — Reactive Architecture ?
REACTIVE
AGILE
EVENT DRIVEN
SCALABLE
AVAILABLE

@glaforge — @smaldini / #DV13-rtweb

!5
Reactor — Reactive Architecture ?
• A good description is available on: 

http://www.reactivemanifesto.org/	

!

• Functional Programming helps as it is stimulus based by nature	

!

• Groovy is a perfect candidate: 

Closures and DSL are first class citizen	

!

• Reactor completes the picture by providing abstractions

@glaforge — @smaldini / #DV13-rtweb

!6
Reactor — Threading model matters
• Context switching hurts performances	

• Locking hurts performances	

• Message passing hurts performances	

• Blocking for a thread hurts performances	

• Creating Threads needs memory

@glaforge — @smaldini / #DV13-rtweb

!7
Reactor — Dealing with performances
• Actors solve the locking and context switching issues 

by becoming state boxes	

• One thread assigned per consumer	

• One thread will ever access a property

• Non Blocking Programming solves thread creation and
waiting issues by delaying logic	

• Callback will be executed when possible (Lazy)	

• Reallocate the blocking time to process something else

@glaforge — @smaldini / #DV13-rtweb

!8
Reactor — LMAX Disruptor and Ring Buffer
• LMAX Disruptor deals with message passing issues	

• Based on a Ring Buffer structure	

• “Mechanical Sympathy” in Disruptor	

!

• http://lmax-exchange.github.com/disruptor/files/
Disruptor-1.0.pdf	

• http://mechanitis.blogspot.co.uk/2011/06/dissecting-disruptorwhats-so-special.html

@glaforge — @smaldini / #DV13-rtweb

!9
Reactor — Disruptor performances

@glaforge — @smaldini / #DV13-rtweb

!10
Reactor — Trisha’s pretty picture of Disruptor
http://mechanitis.blogspot.co.uk/2011/07/dissectingdisruptor-writing-to-ring.html

@glaforge — @smaldini / #DV13-rtweb

!11
Reactor — In love with Disruptor
• Reactor best performances are derived from LMAX Disruptor	

!

• LMAX Disruptor can be considered 

as an evolution of the Actor Model:	

!

• Still avoid locking and deals with context switching	

• Producer/Consumer decoupled	

• Add Pipelining, Batching and more

@glaforge — @smaldini / #DV13-rtweb

!12
Reactor — A foundation part of Spring IO

@glaforge — @smaldini / #DV13-rtweb

!13
Reactor — What is it?
!

• Reactor is a distillation of other libraries and best-practices	

– Elements of other patterns and libraries 

surface throughout Reactor's abstractions	

!

• http://stackoverflow.com/questions/16595393/akka-or-reactor

@glaforge — @smaldini / #DV13-rtweb

!14
Reactor — What can I build with it?
• Reactor applications are reactive	

– Reactive Extensions in .NET	

– Netflix RxJava	

– Observer pattern	

!

• Reactor applications route events based on a Selector	

– Like a routing topic, but can be any object	

– Regex, URI template, Class.isAssingableFrom, custom logic

@glaforge — @smaldini / #DV13-rtweb

!15
Reactor — Landscape

@glaforge — @smaldini / #DV13-rtweb

!16
Reactor — What does it look like?
Create a reactor context
def	
  env	
  =	
  new	
  Environment()	
  
!

Build a reactor
parameter

def	
  reactor	
  =	
  
Reactors.reactor().env(env).dispatcher(RING_BUFFER).get()	
  
!

reactor.on($('topic')){	
  Event<String>	
  ev	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "Hello	
  $ev.data"	
  
}	
  

React on ‘topic’ events

!

reactor.notify('topic',	
  Event.wrap('John	
  Doe'))

Trigger reactor ‘topic’ key
@glaforge — @smaldini / #DV13-rtweb

!17
Reactor — Selectors
• Selectors are the left-hand side of an equality comparison	

!

– A Selector can be created from any object using $(obj) 

(or the long form: Selectors.object(obj))	

!

– A Selector can extract data from the matched key	

!

– Predicate<T> Selectors can be created to match on domainspecific criteria like header values

@glaforge — @smaldini / #DV13-rtweb

!18
Reactor — RegexSelector
• A RegexSelector will match a String by executing the regex
over it	

– R(“some.(.*)”)
– Selectors.regex(“some.(.*)”)

@glaforge — @smaldini / #DV13-rtweb

!19
Reactor — RegexSelector
!

• A RegexSelector will match a String 

by executing the regex over it	

!

– R(“some.(.*)”)
!

– Selectors.regex(“some.(.*)”)

@glaforge — @smaldini / #DV13-rtweb

!20
Reactor — RegexSelector
Use a Regex Selector and capture group
reactor.on(R('some.(.+)')){	
  Event<String>	
  ev	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  def	
  s	
  =	
  ev.headers.get('group1')	
  
}	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
s will be ‘topic’
!

reactor.notify('some.topic',	
  Event.wrap('John	
  Doe'))

Notify a simple String
key to be matched
@glaforge — @smaldini / #DV13-rtweb

!21
Reactor — UriSelector
• A UriTemplateSelector will match a String 

by extracting bits from a URI
!

– U(“/some/{path}”)
– Selectors.uri(“/some/{path}”)

@glaforge — @smaldini / #DV13-rtweb

!22
Reactor — UriSelector
Use a URI Selector and capture fragment
reactor.on(U('/some/**/{topic}')){	
  Event<String>	
  ev	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  def	
  s	
  =	
  ev.headers['topic']	
  
}	
  	
  	
  	
  	
  	
  	
  	
  
s will be ‘topic’
!

reactor.notify('/some/to/topic',	
  Event.wrap('John	
  Doe'))

Notify a simple String
URI key to be matched
@glaforge — @smaldini / #DV13-rtweb

!23
Reactor — Consumer, Function, Supplier, Predicate
public	
  interface	
  Consumer<T>	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  void	
  accept(T	
  t);	
  	
  
}	
  	
  	
  	
  	
  	
  	
  	
  

Generic Callback

!

public	
  interface	
  Supplier<T>	
  {	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  T	
  get();	
  	
  	
  
}	
  

Object Factory

!

public	
  interface	
  Function<T,	
  V>	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  V	
  apply(T	
  t);	
  
}	
  	
  	
  	
  	
  	
  	
  	
  

Map Operation

!

public	
  abstract	
  class	
  Predicate<T>	
  {	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  boolean	
  test(T	
  t);	
  	
  
}	
  	
  	
  
@glaforge — @smaldini / #DV13-rtweb

Filter Operation

!24
Reactor — Streams
●

−
−

Streams allow for composition of functions on data	

Callback++	

Netflix RxJava Observable, JDK 8 Stream
Stream<String>	
  str	
  =	
  obtainStream()	
  

Coerces to Function

!

str.map{	
  it.toUpperCase()	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  .filter{	
  someCondition()	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  .consume{	
  s	
  -­‐>	
  log.info	
  "consumed	
  string	
  $s"	
  }

Coerces to Predicate

@glaforge — @smaldini / #DV13-rtweb

Coerces to Consumer
!25
Reactor — Promises
●

−
−

Promises supersedes Java Future for composition	

Share common functions with Stream
Stateful: only 1 transition allowed
Promise<String>	
  p	
  =	
  doLater()	
  
!

String	
  s	
  =	
  p	
  
	
  .onSuccess	
  {	
  s	
  -­‐>	
  log.info	
  "consumed	
  string	
  $s"	
  }	
  
	
  	
  .onFailure	
  {	
  t	
  -­‐>	
  log.error	
  "$t.message"	
  }	
  
	
  	
  	
  .onComplete	
  {	
  log.info	
  'complete'	
  }	
  
	
  	
  	
  	
  .await(5,	
  SECONDS)	
  
!

p.map{	
  it.toUpperCase()	
  }.consume{s	
  -­‐>	
  log.info	
  "UC:	
  $s"}	
  

Block for a return value
@glaforge — @smaldini / #DV13-rtweb

!26
Reactor — Processor
●

−
−

Thin wrapper around Disruptor RingBuffer
Converts Disruptor API to Reactor API	

Uber fast performance for #UberFastData
Processor<Buffer>	
  proc	
  
!

Operation<Buffer>	
  op	
  =	
  proc.prepare()	
  
op.get().append(data).flip()	
  
op.commit()	
  
!

proc.batch(512)	
  {	
  it.append(data).flip()	
  }

Fill 512 slots and release once
@glaforge — @smaldini / #DV13-rtweb

!27
Reactor — Spring
!

Helpers to integrate Reactor into ApplicationContext	


●

!

−

@EnableReactor for easy configuration	

!

−

Wiring annotated handlers

@glaforge — @smaldini / #DV13-rtweb

!28
Reactor — Spring
Setup Environment

@Configuration	
  
@EnableReactor	
  
class	
  ReactorConfiguration	
  {	
  
!

	
  	
  	
  	
  	
  	
  	
  	
  @Bean	
  Reactor	
  input(Environment	
  env)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Reactors.reactor().env(env)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .dispatcher(RING_BUFFER).get()	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  
!

	
  	
  	
  	
  	
  	
  	
  	
  @Bean	
  Reactor	
  output(Environment	
  env)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Reactors.reactor().env(env)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .dispatcher(RING_BUFFER).get()	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  
}
@glaforge — @smaldini / #DV13-rtweb

!29
Reactor — Spring
@Component	
  
class	
  SimpleHandler	
  {	
  

Inject reactor

!

	
  	
  @Autowired	
  Reactor	
  reactor	
  
!

	
  	
  @Selector('test.topic')	
  void	
  onTestTopic(String	
  s)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Handle	
  data	
  
	
  	
  }	
  
}

Register consumer on @reactor

@glaforge — @smaldini / #DV13-rtweb

!30
Reactor — Spring
●

−
−
●
●

●

DispatcherTaskExecutor 	

Not really a high-scale TaskExecutor	

Used to get Spring components running in same thread as
Reactor Consumers	

ConversionService integration	

PromiseHandlerMethodReturnValueHandler (!)	

ReactorSubscribableChannel

@glaforge — @smaldini / #DV13-rtweb

!31
Reactor — Groovy
●

−
−
−
−

First class citizen language implementation	

@CompileStatic ready	

Prominent use of Closure as Consumers, Functions and
more	

Operator overloading for elegant programming	

Full Reactor system Builder

@glaforge — @smaldini / #DV13-rtweb

!32
Reactor — Groovy
Works with Groovy 2 CompileStatic

Coerce String to $(string)

@CompileStatic	
  
def	
  welcome()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  reactor.on('greetings')	
  {	
  String	
  s	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  reply	
  "hello	
  $s"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  reply	
  "how	
  are	
  you?"	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  

Send data back using
replyTo key header

!

	
  	
  	
  	
  	
  	
  	
  	
  reactor.notify	
  'greetings',	
  'Jon'	
  
!

	
  	
  	
  	
  	
  	
  	
  	
  reactor.send('greetings',	
  'Stephane')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  println	
  it	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  cancel()	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
}

Stop listening for replies

@glaforge — @smaldini / #DV13-rtweb

Coerce data arg to
Event.wrap(data)
Notify & Listen for replies
!33
Reactor — Groovy Promises and Streams
Build an async function

def	
  promise	
  =	
  Promises.task	
  {	
  longStuff();	
  1	
  }	
  get()	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
!

def	
  transformation	
  =	
  promise	
  |	
  {	
  it	
  +	
  1	
  }	
  
transformation.await()	
  ==	
  2	
  	
  	
  	
  	
  	
  

Pipe promise with the
!
def	
  deferredStream	
  =	
  Streams.defer().get()	
  	
  	
  	
  	
  	
  	
  
closure transformation
(deferredStream	
  &	
  {	
  it	
  >	
  2	
  })	
  <<	
  {	
  send(it)	
  }	
  
!

deferredStream	
  <<	
  1	
  <<	
  2	
  <<	
  3	
  <<	
  4

Filter the stream with
the right hand closure
predicate
@glaforge — @smaldini / #DV13-rtweb

Add callback after filter
Send data
!34
Reactor — Groovy Environment
Works with Groovy 2
@CompileStatic

Prepare an environment
builder

GroovyEnvironment.create	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  environment	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  defaultDispatcher	
  =	
  "test"	
  
!

which dispatcher to use
when creating a reactor

	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  dispatcher('test')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  type	
  =	
  DispatcherType.SYNCHRONOUS	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  
Build a standard
}.environment()

Return a ready to
use Environment

@glaforge — @smaldini / #DV13-rtweb

Dispatcher

!35
Reactor — Groovy Environment
Build a named Reactor

GroovyEnvironment.create	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  reactor('test1')	
  {	
  
Intercept the data
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  stream('test')	
  {	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  consume	
  {	
  ev-­‐>	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
stream coming by the
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  log.info	
  ev.data	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
selector $(‘test’)
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  on('test')	
  {	
  
Stream builder
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  reply	
  it	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
}	
  

Attach inline consumers

@glaforge — @smaldini / #DV13-rtweb

!36
Reactor — Extensive Awesomeness
●

TCP Client/Server, with a Netty 4 implementation	


●

Buffer tools	


●

Sequencer support, for event ordering

●

Work Queue support with OoB Java Chronicle implementation	


●

Log Appender

@glaforge — @smaldini / #DV13-rtweb

!37
Reactor — Roadmap
1.1 discussions

●

−

StateBox: a safe tool for concurrent writes	


−

Better Timer management	


−

Spring XD, Spring 4	


−

Exploring Distributed Reactors	

●

Voice your interest and your use-case here

@glaforge — @smaldini / #DV13-rtweb

!38
Reactor — Roadmap
1.1 discussions

●

−

HTTP helpers

−

Improved RingBuffer API for multithreaded consumers
(slow consumers)

−

More Groovy Love: Buffer, TCP, Processor, Time,

@glaforge — @smaldini / #DV13-rtweb

!39
Reactor — Uber Community Contribs
●

−

Meltdown: A Clojure binding by @michaelklishin &
@ifesdjeen 	

https://github.com/clojurewerkz/meltdown

@glaforge — @smaldini / #DV13-rtweb

!40
Reactor — Uber Community Contribs
!

●

−

High Performance Couchbase ingestion by @daschl	

http://nitschinger.at/Using-the-Reactor-Processor-for-HighPerformance-TCP	

!

●

Benefits of using Reactor Processor, TCP and Batching
facilities

@glaforge — @smaldini / #DV13-rtweb

!41
Demo
2
t
r
a
P

Grails
Grails — The Age of Asynchronous
Fact #1:	

– HTTP request thread is critical path	

– Do the barely necessary for fast rendering	

– If it’s long*, do it in a separate thread

@glaforge — @smaldini / #DV13-rtweb

!44
Grails — The Age of Asynchronous
Fact #2:	

– Creating new Threads needs caution	

– Context switching hurts performances	

– Concurrent programming is tricky*

@glaforge — @smaldini / #DV13-rtweb

!45
Grails — The Age of Asynchronous

Fact #3:	

– Burden on your application is never constant	

– Scaling Up is a good start…	

– …And Scaling Out is only next

@glaforge — @smaldini / #DV13-rtweb

!46
Grails — The Age of Asynchronous

So I have to use background threads ?	

But using them might lead to issues and headaches ?	

And what if I really need to scale out ?

@glaforge — @smaldini / #DV13-rtweb

!47
Grails — Reactive Programming Recap
• Adding a level of indirection : 

Driving your application with Events
• Laziness is key
• Scale up/out by tweaking dispatching

@glaforge — @smaldini / #DV13-rtweb

!48
Grails — The Big Picture
Application
Service
Consumer
Service
Consumer

Publish/Subscribe
Events
Bus

Service
Consumer

@glaforge — @smaldini / #DV13-rtweb

Service
Consumer

Service
Consumer

!49
Grails — The Big Picture
Cloud
App
Publish/Subscribe

App
Events
Bus

App

App
App

@glaforge — @smaldini / #DV13-rtweb

!50
Introducing	
  GRAILS-­‐EVENTS	
  plugin
BOOM!

worse slide ever™
@glaforge — @smaldini / #DV13-rtweb

!51
Grails — Origins : Platform-Core plugin
• An initiative to provide modern tools for grails development	

!

• Among them: the Events API	

• An abstraction used in a few Grails applications today to
decouple logic from producers
!

• grails-events can be considered as 

Platform Core Events API 2.0
@glaforge — @smaldini / #DV13-rtweb

!52
Grails — Why a new plugin ?
• New features. And quite a few.	

– Streaming data, Selectors, Queue	

!

• Based on a new solid foundation – Reactor
– Where Platform-core Events best ideas have leaked	

!

• Semantic changes
– But relatively straightforward migration path

@glaforge — @smaldini / #DV13-rtweb

!53
Grails — Why a new plugin ?
• Lightweight, only focused on events	

!

• Ready to be embedded in a future Grails version	

• Complete the asynchronous story	

• Could enable runtime plugin deployment

@glaforge — @smaldini / #DV13-rtweb

!54
Grails — So what Grails Events is about
• Grails Apps and Plugins can use Events to:	

– Listen for plugins/app events	

– Start simple with in-memory eventing (#uberfastdata)	

– Do Asynchronous calls (default)	

– Increase in flexibility if required

@glaforge — @smaldini / #DV13-rtweb

!55
Grails — Installing Grails Events
• It’s a binary plugin (!)	

• Requires Grails 2.2+
repositories	
  {	
  
	
  	
  	
  	
  //...	
  	
  	
  	
  
	
  	
  	
  	
  mavenRepo	
  "http://repo.springsource.org/libs-­‐snapshot"	
  
	
  	
  	
  	
  mavenRepo	
  "http://repo.grails.org/grails/libs-­‐snapshots-­‐local/"	
  
}	
  
!

dependencies	
  {	
  
	
  	
  	
  	
  compile	
  'org.grails.plugins:events:1.0.0.BUILD-­‐SNAPSHOT'	
  
}	
  

@glaforge — @smaldini / #DV13-rtweb

!56
Grails — Semantics: Consumer
• A Consumer:	

– Accepts an Event	

– Is registered in a Service or Events artifact, or by calling on()	

– Can be thread safe 	

• Depending on the dispatcher type	

• Assuming the consumer is not registered more than once

@glaforge — @smaldini / #DV13-rtweb

!57
Grails — Semantics: Selector
• A Selector:	

– Matches an event key	

– Is paired with a consumer during its registration
– Any bean method can be transformed into consumer
with @Selector

@glaforge — @smaldini / #DV13-rtweb

!58
Grails — Semantics: Reactor
• A Reactor:	

– Is a dedicated Consumer Registry	

– Has an assigned Dispatcher	

– Uses a specific Event Router	

!

• Usually, if the Dispatcher doesn’t need to be adapted, reuse the
default reactor grailsReactor

@glaforge — @smaldini / #DV13-rtweb

!59
Grails — Pattern Examples : Event Driven CQRS
http://martinfowler.com/bliki/CQRS.html

Save a GORM entity
SaveService
GORM

DB

PostProcessingService

Insert Record

@glaforge — @smaldini / #DV13-rtweb

Trigger afterInsert
event

Consume afterInsert events

!60
Grails — Pattern Examples : Modular Architecture
Core application untouched

Trigger ‘request’ event

Main Application

RequestService

Notification Plugin

NotificationService

Create a decoupled module
@glaforge — @smaldini / #DV13-rtweb

Consume ‘request’ events
!61
Grails — Pattern Examples : Background Processing
Return immediately
Grails Controller

REST service

Request Service

HTTP Request

Trigger ‘request’
event (async)

Long REST call
@glaforge — @smaldini / #DV13-rtweb

!62
Grails — Sending Events (grails-platform-core)
def	
  user	
  =	
  new	
  User(params).save()	
  
!

event('mailRegistration',	
  user)	
  
	
  	
  
//event('mailRegistration',	
  user).waitFor()	
  
	
  	
  
//event	
  topic:'mailRegistration',	
  data:user	
  
	
  	
  
//event	
  topic:'mailRegistration',	
  data:user,	
  fork:false	
  
	
  	
  
render(view:'sendingRegistrationMail')

@glaforge — @smaldini / #DV13-rtweb

!63
Grails — Sending Events (grails-events)
def	
  user	
  =	
  new	
  User(params).save()	
  
!

event('mailRegistration',	
  user)	
  
	
  	
  	
  	
  	
  	
  	
  
event('mailRegistration',	
  user)	
  {	
  
	
  	
  	
  	
  if(it	
  ==	
  ‘end')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  cancel()	
  
	
  	
  	
  	
  }	
  
}	
  	
  	
  

Non blocking call to
trigger app consumers

Do things on each reply
Map notation

!

//	
  event	
  key:	
  'mailRegistration',	
  data:	
  user	
  
!

render(view:	
  'sendingRegistrationMail')
@glaforge — @smaldini / #DV13-rtweb

!64
Grails — Consuming Events (grails-platform-core)
class	
  UserService{	
  
	
  	
  	
  	
  @grails.events.Listener	
  
	
  	
  	
  	
  def	
  mailRegistration(User	
  user)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  sendMail	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  to	
  user.mail	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  subject	
  "Confirmation"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html	
  g.render(template:"userMailConfirmation")	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
!

	
  	
  	
  	
  @grails.events.Listener(topic=	
  "mailRegistration")	
  
	
  	
  	
  	
  def	
  mailRegistration2(org.grails.plugin.platform.events.EventMessage	
  msg)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  sendMail{	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  to	
  msg.data.mail	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  subject	
  "Confirmation"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html	
  g.render(template:	
  "userMailConfirmation")	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
}

@glaforge — @smaldini / #DV13-rtweb

!65
Grails — Consuming Events (grails-events)
Consume on
Selector(method name)

class	
  UserService{	
  
	
  	
  
	
  	
  	
  	
  @reactor.spring.annotation.Selector	
  
	
  	
  	
  	
  def	
  mailRegistration(User	
  user){	
  
	
  	
  	
  	
  	
  	
  	
  	
  sendMail{	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  to	
  user.mail	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  subject	
  "Confirmation"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html	
  g.render(template:	
  "userMailConfirmation")	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  

Consume on this
specific topic

!

	
  	
  	
  	
  @reactor.spring.annotation.Selector("mailRegistration")	
  
	
  	
  	
  	
  def	
  mailRegistration2(reactor.event.Event	
  msg){	
  
	
  	
  	
  	
  	
  	
  	
  	
  sendMail{	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  to	
  msg.data.mail	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  subject	
  "Confirmation"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  html	
  g.render(template:"userMailConfirmation")	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
}

@glaforge — @smaldini / #DV13-rtweb

Event typed signature
to inspect enveloppe
(‘headers…)
!66
Grails — A new Artifact conf/XxxxEvents
includes	
  =	
  ['default']	
  

Merge with DefaultsEvents

!

doWithReactor	
  =	
  {	
  
	
  	
  	
  	
  reactor(EventsApi.GRAILS_REACTOR)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  on('someTopic')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  reply	
  'test'	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  reactor(‘someGormReactor')	
  {	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  dispatcher	
  =	
  new	
  SynchronousDispatcher()	
  
	
  	
  	
  	
  	
  	
  	
  	
  ext	
  'gorm',	
  true	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  

Build a GroovyEnvironment

Reactor Groovy Builders

!

Grails extension: accept GORM events

	
  	
  	
  	
  	
  	
  	
  	
  stream	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  consume	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  log.info	
  "Some	
  gorm	
  event	
  is	
  flowing	
  with	
  data	
  $it.data"	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }.when(Throwable)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  log.error	
  "Ow	
  snap!",	
  it	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
}
@glaforge — @smaldini / #DV13-rtweb
!67
Grails — Reactor awesomeness : Selectors
• Listen for arbitrary keys	

• import static reactor.event.selector.Selectors.*
on(T(SpecificClassType))	
  {	
  
Listen for SpecificClassType
	
  	
  	
  	
  	
  	
  	
  	
  reply	
  it	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
}	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
!

Send using right key type

event(new	
  SpecificClassType(),	
  'data')	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
!
!

Listen for an URI

on(uri(‘/some/{captureIt}'))	
  {	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  reply	
  it.headers.captureIt	
  
}	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
!

Send using matching URI

event('/some/hourray',	
  'data')	
  	
  	
  	
  
@glaforge — @smaldini / #DV13-rtweb

!68
Grails — Reactor awesomeness : Stream API
• Reactive Extensions programming style	

• Avoid callback hell
Build a Stream to capture any reply
$(‘test’) consumers may reply
withStream	
  {	
  
	
  	
  	
  	
  event(key:	
  'test',	
  data:	
  1)	
  
}.when(Exception,	
  {	
  
If a consumer fails
	
  	
  	
  	
  log.info	
  "exception:$it"	
  
}).map	
  {	
  
Transform result
	
  	
  	
  	
  callExternalService(it)	
  
}.consume('clientKey',	
  reactor('browser'))
Reroute to key ‘clientKey’
on Reactor ‘browser’
@glaforge — @smaldini / #DV13-rtweb

!69
Grails — Reactor awesomeness: Promise API
• Grails 2.3 Promises become a Reactor Promises	

• Benefits from Dispatcher overriding
• Powerful once Combined with Consumers
dispatcher(ReactorPromise.PromiseDispatcher)	
  {	
  
	
  	
  	
  	
  type	
  =	
  DispatcherType.RingBuffer	
  
	
  	
  	
  	
  backlog	
  =	
  512	
  
}
task	
  {	
  
	
  	
  	
  	
  def	
  res	
  =	
  
longProcessing()	
  
	
  	
  	
  	
  render	
  res	
  
}
@glaforge — @smaldini / #DV13-rtweb

!70
Grails — Reactor awesomeness : Routing
• During event dispatching, consumers list is selected	

• Publish Subscribe is the default	

• Possible to assign different routing strategy
reactor('test1')	
  {	
  
	
  	
  	
  	
  routingStrategy	
  'round-­‐robin'	
  
	
  	
  	
  	
  on('test')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  reply	
  '1'	
  
Will reply 1, 2, 1, 2, 1, 2…
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  on('test')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  reply	
  '2'	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  
}
@glaforge — @smaldini / #DV13-rtweb

!71
Grails — Extensibility
!

• Main extension points:	

– Dispatcher, Selector, Registry, EventRouter, Consumer
!

• Metadata in Reactor Events DSL:	

– ext(‘someExtension’, [ ‘doStuff’: true ])

@glaforge — @smaldini / #DV13-rtweb

!72
Grails — GORM events
• GORM is now an extension	

– Using ext(‘gorm’, true) on any candidate reactor	

– Applicable Selectors: simple topic form (beforeInsert...)	

– A boolean reply is evaluated as a cancel directive
reactor('someGormReactor'){	
  
	
  	
  	
  	
  dispatcher	
  =	
  new	
  SynchronousDispatcher()	
  
	
  	
  	
  	
  ext	
  'gorm',	
  true	
  
@Selector(reactor	
  =	
  'someGormReactor')	
  
}	
  	
  
@ReplyTo	
  
boolean	
  beforeValidate(Book	
  b){	
  
	
  	
  	
  	
  false	
  
}
@glaforge — @smaldini / #DV13-rtweb

!73
GRAILS-­‐EVENTS-­‐PUSH	
  plugin
Eventing over HTTP!

@glaforge — @smaldini / #DV13-rtweb

!74
Grails — Pattern Examples : “Realtime” web
Push reply to browser: Websocket, SSE, long-polling…

Reply a new event

ResponseService

Browser

Return immediately

@glaforge — @smaldini / #DV13-rtweb

Grails Controller

RequestService

Trigger async event

!75
Grails — An elegant solution to browser push
• Powered by Atmosphere 2	

• Automatically picks an adapted protocol:	

– WebSockets, ServerSideEvent, Streaming, Polling…	

• Consumer bridges for server-to-client push	

• Reactor bridge for client-to-server push	

• Javascript library

@glaforge — @smaldini / #DV13-rtweb

!76
Grails — Installing Grails Events Push
1. Install Grails Events plugin	

2. Install Grails Events Push plugin
grails.servlet.version	
  =	
  "3.0"	
  
grails.tomcat.nio	
  =	
  true	
  
!

Use a “long-connection” friendly
tomcat configuration

grails.project.dependency.resolution	
  =	
  {	
  
	
  	
  	
  	
  repositories	
  {	
  
	
  	
  	
  	
  //...	
  
	
  	
  	
  	
  	
  	
  	
  	
  mavenRepo	
  "https://oss.sonatype.org/content/repositories/snapshots"	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  dependencies	
  {	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  //...	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  compile	
  'org.grails.plugins:events:1.0.0.BUILD-­‐SNAPSHOT'	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  plugins	
  {	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  //...	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  runtime	
  ":jquery:1.10.2"	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  runtime	
  ":events-­‐push:1.0.0.BUILD-­‐SNAPSHOT"	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  }	
  
}

@glaforge — @smaldini / #DV13-rtweb

!77
Grails — grails-events-push Lifecycle 1 - Handshake

Browser

EventsPushHandler

Adapt Protocol and Open
new persistent connection

@glaforge — @smaldini / #DV13-rtweb

!78
Grails — grails-events-push Lifecycle 2 - Register
Consumer registered on all Reactor with
‘browser’ extension enabled
Browser

Reactor(s)

Bridge a Client Consumer with a
remote Reactor Consumer

@glaforge — @smaldini / #DV13-rtweb

!79
Grails — grails-events-push Lifecycle 3 - Notify
RequestService consumes on matching
Selector within the ‘browser’ Reactor
Browser

‘browser’ Reactor

RequestService

Notify any key

@glaforge — @smaldini / #DV13-rtweb

!80
Grails — grails-events-push Lifecycle 4 - Consume
Notify ‘browser’ enabled
Reactor and match key
Browser

Reactor(s)

ResponseService

Push event (WS, SSE…)

@glaforge — @smaldini / #DV13-rtweb

!81
Grails — Generating Simple Browsers bridges
includes	
  =	
  'push'	
  
!

Conventional name to
override ‘browser’ reactor

doWithReactor	
  =	
  {	
  
	
  	
  	
  	
  reactor('browser')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  ext	
  'browser',	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'control',	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'move',	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'fire',	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'leave'	
  
	
  	
  	
  	
  	
  	
  	
  	
  ]	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  	
  reactor(‘grailsReactor')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  ext	
  'browser',	
  ['sleepBrowser']	
  

Bridge browser to these reactor
consumers $(‘control),…

!

	
  	
  	
  	
  	
  	
  	
  	
  stream(‘sleepBrowser')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  filter	
  {	
   	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  it.data	
  ==	
  'no'	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
}

@glaforge — @smaldini / #DV13-rtweb

Bridge browser to this reactor
consumer $(‘sleepBrowser)

Prevent data ‘no’ to be
dispatched to browser bridges
!82
Grails — React on server side events
Inject grailsEvents.js (requires resources plugin)
Create a connection
between the browser and
the current Grails app
Listen for $(‘afterInsert’) events

@glaforge — @smaldini / #DV13-rtweb

!83
Grails — Generating Advanced Browsers bridges
includes	
  =	
  ['push']	
  
!

Include PushEvents (configure a
reactor for events from Browsers)

doWithReactor	
  =	
  {	
  
	
  	
  	
  	
  reactor(‘grailsReactor')	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  ext	
  'gorm',	
  true	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  ext	
  'browser',	
  [	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'test':	
  true,	
  
	
   	
   	
   	
  	
  	
  	
  	
  	
  	
  'afterInsert':	
  [	
  
	
   	
   	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  browserFilter:	
  {m,	
  r	
  -­‐>	
  true	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ],	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (R("sampleBro-­‐.*"))	
  :	
  true,	
  
	
  	
  	
  	
  	
  	
  	
  	
  ]	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  reactor(EventsPushConstants.FROM_BROWSERS)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  ext	
  'browser',	
  [R("sampleBro-­‐.*")]	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  }	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
}	
  

Listen on GORM events

Extension to bridge
Browsers consumers to
Server-side pair

Events are only routed, from
Browsers to bridged Browsers

@glaforge — @smaldini / #DV13-rtweb

Override “From Browsers” reactor
and bridge consumers

!84
Grails — The Bad Stuff
• events-si : Events API on top of Spring Integration	

– Not here (just) yet	

!

• events-vertx : Abandoned experiment	

– Working around Distributed Reactor	

!

• Stream DSL could be optimized	

– Reducing the number of objects

@glaforge — @smaldini / #DV13-rtweb

!85
Grails — Roadmap
• events: 	

– Document, especially for Migration from Platform Core	

– Stick with latest awesome features from Reactor	

• Still Many API to expose: Processors, Buffer, TCP, Queues,
Sequencer…	

!

• events-push -> events-atmosphere : 	

– Add support for replyTo	

– extract to standalone module : reactor-atmosphere
@glaforge — @smaldini / #DV13-rtweb

!86
Grails — Roadmap
• events-sockjs:	

– Involves Reactor work here 	

!

• events-si: 	

– Supports new events plugin	

!

• events-xx:	

– The plugin where you are the hero

@glaforge — @smaldini / #DV13-rtweb

!87
Demo
4
t
r
a
P

Summary
Groovy, Reactor, Grails and the realtime web
• Embrace modern reactive architectures with Groovy,
Reactor and Grails!	

• Groovy is a versatile language, that enables development of
concise and functional oriented applications	

• Reactor fuels your asynchronous and reactive applications
with its ultra fast dispatching engine and non-blocking model.	

• Grails supports your today's and tomorrow's web app design,
tooled with the right plugins you are prepared for responsive
and interactive applications
@glaforge — @smaldini / #DV13-rtweb

!90

More Related Content

What's hot

When Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the EnterpriseWhen Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the Enterprisebenbrowning
 
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 BostonScaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 Bostonbenbrowning
 
Node.js, toy or power tool?
Node.js, toy or power tool?Node.js, toy or power tool?
Node.js, toy or power tool?Ovidiu Dimulescu
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxbobmcwhirter
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...bobmcwhirter
 
DataMapper on Infinispan
DataMapper on InfinispanDataMapper on Infinispan
DataMapper on InfinispanLance Ball
 
TorqueBox - Ultrapassando a fronteira entre Java e Ruby
TorqueBox - Ultrapassando a fronteira entre Java e RubyTorqueBox - Ultrapassando a fronteira entre Java e Ruby
TorqueBox - Ultrapassando a fronteira entre Java e RubyBruno Oliveira
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tourcacois
 
Java EE Servlet JSP Tutorial- Cookbook 1
Java EE Servlet JSP Tutorial- Cookbook 1Java EE Servlet JSP Tutorial- Cookbook 1
Java EE Servlet JSP Tutorial- Cookbook 1billdigman
 
Node.js Enterprise Middleware
Node.js Enterprise MiddlewareNode.js Enterprise Middleware
Node.js Enterprise MiddlewareBehrad Zari
 
GWT is Smarter Than You
GWT is Smarter Than YouGWT is Smarter Than You
GWT is Smarter Than YouRobert Cooper
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage libraryAn introduction and future of Ruby coverage library
An introduction and future of Ruby coverage librarymametter
 
Threads Needles Stacks Heaps - Java edition
Threads Needles Stacks Heaps - Java editionThreads Needles Stacks Heaps - Java edition
Threads Needles Stacks Heaps - Java editionOvidiu Dimulescu
 
Java EE Servlet/JSP Tutorial- Cookbook 2
Java EE Servlet/JSP Tutorial- Cookbook 2Java EE Servlet/JSP Tutorial- Cookbook 2
Java EE Servlet/JSP Tutorial- Cookbook 2billdigman
 
Lagergren jvmls-2014-final
Lagergren jvmls-2014-finalLagergren jvmls-2014-final
Lagergren jvmls-2014-finalMarcus Lagergren
 
Understanding the Single Thread Event Loop
Understanding the Single Thread Event LoopUnderstanding the Single Thread Event Loop
Understanding the Single Thread Event LoopTorontoNodeJS
 
When Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of TorqueboxWhen Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of Torqueboxrockyjaiswal
 
Shall we play a game?
Shall we play a game?Shall we play a game?
Shall we play a game?Maciej Lasyk
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Dinh Pham
 

What's hot (20)

When Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the EnterpriseWhen Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the Enterprise
 
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 BostonScaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
 
Node.js, toy or power tool?
Node.js, toy or power tool?Node.js, toy or power tool?
Node.js, toy or power tool?
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
 
DataMapper on Infinispan
DataMapper on InfinispanDataMapper on Infinispan
DataMapper on Infinispan
 
TorqueBox - Ultrapassando a fronteira entre Java e Ruby
TorqueBox - Ultrapassando a fronteira entre Java e RubyTorqueBox - Ultrapassando a fronteira entre Java e Ruby
TorqueBox - Ultrapassando a fronteira entre Java e Ruby
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 
Java EE Servlet JSP Tutorial- Cookbook 1
Java EE Servlet JSP Tutorial- Cookbook 1Java EE Servlet JSP Tutorial- Cookbook 1
Java EE Servlet JSP Tutorial- Cookbook 1
 
Node js internal
Node js internalNode js internal
Node js internal
 
Node.js Enterprise Middleware
Node.js Enterprise MiddlewareNode.js Enterprise Middleware
Node.js Enterprise Middleware
 
GWT is Smarter Than You
GWT is Smarter Than YouGWT is Smarter Than You
GWT is Smarter Than You
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage libraryAn introduction and future of Ruby coverage library
An introduction and future of Ruby coverage library
 
Threads Needles Stacks Heaps - Java edition
Threads Needles Stacks Heaps - Java editionThreads Needles Stacks Heaps - Java edition
Threads Needles Stacks Heaps - Java edition
 
Java EE Servlet/JSP Tutorial- Cookbook 2
Java EE Servlet/JSP Tutorial- Cookbook 2Java EE Servlet/JSP Tutorial- Cookbook 2
Java EE Servlet/JSP Tutorial- Cookbook 2
 
Lagergren jvmls-2014-final
Lagergren jvmls-2014-finalLagergren jvmls-2014-final
Lagergren jvmls-2014-final
 
Understanding the Single Thread Event Loop
Understanding the Single Thread Event LoopUnderstanding the Single Thread Event Loop
Understanding the Single Thread Event Loop
 
When Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of TorqueboxWhen Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of Torquebox
 
Shall we play a game?
Shall we play a game?Shall we play a game?
Shall we play a game?
 
Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?Asynchronous I/O in NodeJS - new standard or challenges?
Asynchronous I/O in NodeJS - new standard or challenges?
 

Similar to Reactor grails realtime web devoxx 2013

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
 
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019Loiane Groner
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...Codemotion
 
Intro to Reactor
Intro to ReactorIntro to Reactor
Intro to ReactorJon Brisbin
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorVMware Tanzu
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptJohn Stevenson
 
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
 
apachecamelk-april2019-190409093034.pdf
apachecamelk-april2019-190409093034.pdfapachecamelk-april2019-190409093034.pdf
apachecamelk-april2019-190409093034.pdfssuserbb9f511
 
Apache Camel K - Copenhagen v2
Apache Camel K - Copenhagen v2Apache Camel K - Copenhagen v2
Apache Camel K - Copenhagen v2Claus Ibsen
 
Apache Camel K - Copenhagen
Apache Camel K - CopenhagenApache Camel K - Copenhagen
Apache Camel K - CopenhagenClaus Ibsen
 
Full-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConf
Full-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConfFull-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConf
Full-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConfLoiane Groner
 
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018Loiane Groner
 
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java GirlFull-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java GirlLoiane Groner
 
Ractor's speed is not light-speed
Ractor's speed is not light-speedRactor's speed is not light-speed
Ractor's speed is not light-speedSATOSHI TAGOMORI
 
Ratpack Web Framework
Ratpack Web FrameworkRatpack Web Framework
Ratpack Web FrameworkDaniel Woods
 
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Zach Lendon
 
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementMidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementZach Lendon
 
GraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices SolutionGraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices SolutionRoberto Cortez
 
Reactive Streams - László van den Hoek
Reactive Streams - László van den HoekReactive Streams - László van den Hoek
Reactive Streams - László van den HoekRubiX BV
 

Similar to Reactor grails realtime web devoxx 2013 (20)

Reactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalReactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-final
 
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
 
Intro to Reactor
Intro to ReactorIntro to Reactor
Intro to Reactor
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and Reactor
 
apachecamelk-april2019-190409093034.pdf
apachecamelk-april2019-190409093034.pdfapachecamelk-april2019-190409093034.pdf
apachecamelk-april2019-190409093034.pdf
 
Apache Camel K - Copenhagen v2
Apache Camel K - Copenhagen v2Apache Camel K - Copenhagen v2
Apache Camel K - Copenhagen v2
 
Apache Camel K - Copenhagen
Apache Camel K - CopenhagenApache Camel K - Copenhagen
Apache Camel K - Copenhagen
 
Speedy TDD with Rails
Speedy TDD with RailsSpeedy TDD with Rails
Speedy TDD with Rails
 
Full-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConf
Full-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConfFull-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConf
Full-Stack Reativo com Spring WebFlux + Angular - FiqueEmCasaConf
 
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
 
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java GirlFull-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
 
Ractor's speed is not light-speed
Ractor's speed is not light-speedRactor's speed is not light-speed
Ractor's speed is not light-speed
 
Ratpack Web Framework
Ratpack Web FrameworkRatpack Web Framework
Ratpack Web Framework
 
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
 
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementMidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
 
GraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices SolutionGraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices Solution
 
Reactive Streams - László van den Hoek
Reactive Streams - László van den HoekReactive Streams - László van den Hoek
Reactive Streams - László van den Hoek
 

More from Stéphane Maldini

Multi-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocketMulti-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocketSté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
 
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
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive ProgrammingStéphane Maldini
 
Designing for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive StreamsDesigning for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive StreamsStéphane Maldini
 
Reactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServicesReactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServicesSté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
 

More from Stéphane Maldini (14)

The value of reactive
The value of reactiveThe value of reactive
The value of reactive
 
Multi-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocketMulti-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocket
 
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)
 
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
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive Programming
 
Designing for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive StreamsDesigning for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive Streams
 
Reactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServicesReactor, Reactive streams and MicroServices
Reactor, Reactive streams and MicroServices
 
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
 
Eventsggx
EventsggxEventsggx
Eventsggx
 

Recently uploaded

Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 

Recently uploaded (20)

Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 

Reactor grails realtime web devoxx 2013

  • 1. Groovy, Reactor, Grails 
 & the realtime web Guillaume Laforge 
 @glaforge ! Stéphane Maldini
 @smaldini !
  • 2. Stéphane Maldini Consultant and Reactor committer at . ! @smaldini
  • 4. Reactor — Housekeeping ! • Tweet questions during the presentation – @ProjectReactor ! • Stop us anywhere if you have a question – There are no stupid questions, only stupid answers! @glaforge — @smaldini / #DV13-rtweb !4
  • 5. Reactor — Reactive Architecture ? REACTIVE AGILE EVENT DRIVEN SCALABLE AVAILABLE @glaforge — @smaldini / #DV13-rtweb !5
  • 6. Reactor — Reactive Architecture ? • A good description is available on: 
 http://www.reactivemanifesto.org/ ! • Functional Programming helps as it is stimulus based by nature ! • Groovy is a perfect candidate: 
 Closures and DSL are first class citizen ! • Reactor completes the picture by providing abstractions @glaforge — @smaldini / #DV13-rtweb !6
  • 7. Reactor — Threading model matters • Context switching hurts performances • Locking hurts performances • Message passing hurts performances • Blocking for a thread hurts performances • Creating Threads needs memory @glaforge — @smaldini / #DV13-rtweb !7
  • 8. Reactor — Dealing with performances • Actors solve the locking and context switching issues 
 by becoming state boxes • One thread assigned per consumer • One thread will ever access a property
 • Non Blocking Programming solves thread creation and waiting issues by delaying logic • Callback will be executed when possible (Lazy) • Reallocate the blocking time to process something else @glaforge — @smaldini / #DV13-rtweb !8
  • 9. Reactor — LMAX Disruptor and Ring Buffer • LMAX Disruptor deals with message passing issues • Based on a Ring Buffer structure • “Mechanical Sympathy” in Disruptor ! • http://lmax-exchange.github.com/disruptor/files/ Disruptor-1.0.pdf • http://mechanitis.blogspot.co.uk/2011/06/dissecting-disruptorwhats-so-special.html @glaforge — @smaldini / #DV13-rtweb !9
  • 10. Reactor — Disruptor performances @glaforge — @smaldini / #DV13-rtweb !10
  • 11. Reactor — Trisha’s pretty picture of Disruptor http://mechanitis.blogspot.co.uk/2011/07/dissectingdisruptor-writing-to-ring.html @glaforge — @smaldini / #DV13-rtweb !11
  • 12. Reactor — In love with Disruptor • Reactor best performances are derived from LMAX Disruptor ! • LMAX Disruptor can be considered 
 as an evolution of the Actor Model: ! • Still avoid locking and deals with context switching • Producer/Consumer decoupled • Add Pipelining, Batching and more @glaforge — @smaldini / #DV13-rtweb !12
  • 13. Reactor — A foundation part of Spring IO @glaforge — @smaldini / #DV13-rtweb !13
  • 14. Reactor — What is it? ! • Reactor is a distillation of other libraries and best-practices – Elements of other patterns and libraries 
 surface throughout Reactor's abstractions ! • http://stackoverflow.com/questions/16595393/akka-or-reactor @glaforge — @smaldini / #DV13-rtweb !14
  • 15. Reactor — What can I build with it? • Reactor applications are reactive – Reactive Extensions in .NET – Netflix RxJava – Observer pattern ! • Reactor applications route events based on a Selector – Like a routing topic, but can be any object – Regex, URI template, Class.isAssingableFrom, custom logic @glaforge — @smaldini / #DV13-rtweb !15
  • 16. Reactor — Landscape @glaforge — @smaldini / #DV13-rtweb !16
  • 17. Reactor — What does it look like? Create a reactor context def  env  =  new  Environment()   ! Build a reactor parameter def  reactor  =   Reactors.reactor().env(env).dispatcher(RING_BUFFER).get()   ! reactor.on($('topic')){  Event<String>  ev  -­‐>                  println  "Hello  $ev.data"   }   React on ‘topic’ events ! reactor.notify('topic',  Event.wrap('John  Doe')) Trigger reactor ‘topic’ key @glaforge — @smaldini / #DV13-rtweb !17
  • 18. Reactor — Selectors • Selectors are the left-hand side of an equality comparison ! – A Selector can be created from any object using $(obj) 
 (or the long form: Selectors.object(obj)) ! – A Selector can extract data from the matched key ! – Predicate<T> Selectors can be created to match on domainspecific criteria like header values @glaforge — @smaldini / #DV13-rtweb !18
  • 19. Reactor — RegexSelector • A RegexSelector will match a String by executing the regex over it – R(“some.(.*)”) – Selectors.regex(“some.(.*)”) @glaforge — @smaldini / #DV13-rtweb !19
  • 20. Reactor — RegexSelector ! • A RegexSelector will match a String 
 by executing the regex over it ! – R(“some.(.*)”) ! – Selectors.regex(“some.(.*)”) @glaforge — @smaldini / #DV13-rtweb !20
  • 21. Reactor — RegexSelector Use a Regex Selector and capture group reactor.on(R('some.(.+)')){  Event<String>  ev  -­‐>                  def  s  =  ev.headers.get('group1')   }                                 s will be ‘topic’ ! reactor.notify('some.topic',  Event.wrap('John  Doe')) Notify a simple String key to be matched @glaforge — @smaldini / #DV13-rtweb !21
  • 22. Reactor — UriSelector • A UriTemplateSelector will match a String 
 by extracting bits from a URI ! – U(“/some/{path}”) – Selectors.uri(“/some/{path}”) @glaforge — @smaldini / #DV13-rtweb !22
  • 23. Reactor — UriSelector Use a URI Selector and capture fragment reactor.on(U('/some/**/{topic}')){  Event<String>  ev  -­‐>                  def  s  =  ev.headers['topic']   }                 s will be ‘topic’ ! reactor.notify('/some/to/topic',  Event.wrap('John  Doe')) Notify a simple String URI key to be matched @glaforge — @smaldini / #DV13-rtweb !23
  • 24. Reactor — Consumer, Function, Supplier, Predicate public  interface  Consumer<T>  {                  void  accept(T  t);     }                 Generic Callback ! public  interface  Supplier<T>  {                    T  get();       }   Object Factory ! public  interface  Function<T,  V>  {                  V  apply(T  t);   }                 Map Operation ! public  abstract  class  Predicate<T>  {                    boolean  test(T  t);     }       @glaforge — @smaldini / #DV13-rtweb Filter Operation !24
  • 25. Reactor — Streams ● − − Streams allow for composition of functions on data Callback++ Netflix RxJava Observable, JDK 8 Stream Stream<String>  str  =  obtainStream()   Coerces to Function ! str.map{  it.toUpperCase()  }                  .filter{  someCondition()  }                  .consume{  s  -­‐>  log.info  "consumed  string  $s"  } Coerces to Predicate @glaforge — @smaldini / #DV13-rtweb Coerces to Consumer !25
  • 26. Reactor — Promises ● − − Promises supersedes Java Future for composition Share common functions with Stream Stateful: only 1 transition allowed Promise<String>  p  =  doLater()   ! String  s  =  p    .onSuccess  {  s  -­‐>  log.info  "consumed  string  $s"  }      .onFailure  {  t  -­‐>  log.error  "$t.message"  }        .onComplete  {  log.info  'complete'  }          .await(5,  SECONDS)   ! p.map{  it.toUpperCase()  }.consume{s  -­‐>  log.info  "UC:  $s"}   Block for a return value @glaforge — @smaldini / #DV13-rtweb !26
  • 27. Reactor — Processor ● − − Thin wrapper around Disruptor RingBuffer Converts Disruptor API to Reactor API Uber fast performance for #UberFastData Processor<Buffer>  proc   ! Operation<Buffer>  op  =  proc.prepare()   op.get().append(data).flip()   op.commit()   ! proc.batch(512)  {  it.append(data).flip()  } Fill 512 slots and release once @glaforge — @smaldini / #DV13-rtweb !27
  • 28. Reactor — Spring ! Helpers to integrate Reactor into ApplicationContext ● ! − @EnableReactor for easy configuration ! − Wiring annotated handlers @glaforge — @smaldini / #DV13-rtweb !28
  • 29. Reactor — Spring Setup Environment @Configuration   @EnableReactor   class  ReactorConfiguration  {   !                @Bean  Reactor  input(Environment  env)  {                                  Reactors.reactor().env(env)                                                  .dispatcher(RING_BUFFER).get()                  }                 !                @Bean  Reactor  output(Environment  env)  {                                  Reactors.reactor().env(env)                                                  .dispatcher(RING_BUFFER).get()                  }                 } @glaforge — @smaldini / #DV13-rtweb !29
  • 30. Reactor — Spring @Component   class  SimpleHandler  {   Inject reactor !    @Autowired  Reactor  reactor   !    @Selector('test.topic')  void  onTestTopic(String  s)  {                      //  Handle  data      }   } Register consumer on @reactor @glaforge — @smaldini / #DV13-rtweb !30
  • 31. Reactor — Spring ● − − ● ● ● DispatcherTaskExecutor Not really a high-scale TaskExecutor Used to get Spring components running in same thread as Reactor Consumers ConversionService integration PromiseHandlerMethodReturnValueHandler (!) ReactorSubscribableChannel @glaforge — @smaldini / #DV13-rtweb !31
  • 32. Reactor — Groovy ● − − − − First class citizen language implementation @CompileStatic ready Prominent use of Closure as Consumers, Functions and more Operator overloading for elegant programming Full Reactor system Builder @glaforge — @smaldini / #DV13-rtweb !32
  • 33. Reactor — Groovy Works with Groovy 2 CompileStatic Coerce String to $(string) @CompileStatic   def  welcome()  {                  reactor.on('greetings')  {  String  s  -­‐>                                  reply  "hello  $s"                                  reply  "how  are  you?"                  }   Send data back using replyTo key header !                reactor.notify  'greetings',  'Jon'   !                reactor.send('greetings',  'Stephane')  {                                  println  it                                  cancel()                  }   } Stop listening for replies @glaforge — @smaldini / #DV13-rtweb Coerce data arg to Event.wrap(data) Notify & Listen for replies !33
  • 34. Reactor — Groovy Promises and Streams Build an async function def  promise  =  Promises.task  {  longStuff();  1  }  get()                       ! def  transformation  =  promise  |  {  it  +  1  }   transformation.await()  ==  2             Pipe promise with the ! def  deferredStream  =  Streams.defer().get()               closure transformation (deferredStream  &  {  it  >  2  })  <<  {  send(it)  }   ! deferredStream  <<  1  <<  2  <<  3  <<  4 Filter the stream with the right hand closure predicate @glaforge — @smaldini / #DV13-rtweb Add callback after filter Send data !34
  • 35. Reactor — Groovy Environment Works with Groovy 2 @CompileStatic Prepare an environment builder GroovyEnvironment.create  {                  environment  {                                  defaultDispatcher  =  "test"   ! which dispatcher to use when creating a reactor                                dispatcher('test')  {                                                  type  =  DispatcherType.SYNCHRONOUS                                  }                  }                 Build a standard }.environment() Return a ready to use Environment @glaforge — @smaldini / #DV13-rtweb Dispatcher !35
  • 36. Reactor — Groovy Environment Build a named Reactor GroovyEnvironment.create  {                  reactor('test1')  {   Intercept the data                                stream('test')  {                                                                                  consume  {  ev-­‐>                                                           stream coming by the                                                                log.info  ev.data                                       selector $(‘test’)                                                }                                                                              }                                                                                                                                    on('test')  {   Stream builder                                                reply  it                                  }                  }                                                                                                             }   Attach inline consumers @glaforge — @smaldini / #DV13-rtweb !36
  • 37. Reactor — Extensive Awesomeness ● TCP Client/Server, with a Netty 4 implementation ● Buffer tools ● Sequencer support, for event ordering ● Work Queue support with OoB Java Chronicle implementation ● Log Appender @glaforge — @smaldini / #DV13-rtweb !37
  • 38. Reactor — Roadmap 1.1 discussions ● − StateBox: a safe tool for concurrent writes − Better Timer management − Spring XD, Spring 4 − Exploring Distributed Reactors ● Voice your interest and your use-case here @glaforge — @smaldini / #DV13-rtweb !38
  • 39. Reactor — Roadmap 1.1 discussions ● − HTTP helpers − Improved RingBuffer API for multithreaded consumers (slow consumers) − More Groovy Love: Buffer, TCP, Processor, Time, @glaforge — @smaldini / #DV13-rtweb !39
  • 40. Reactor — Uber Community Contribs ● − Meltdown: A Clojure binding by @michaelklishin & @ifesdjeen https://github.com/clojurewerkz/meltdown @glaforge — @smaldini / #DV13-rtweb !40
  • 41. Reactor — Uber Community Contribs ! ● − High Performance Couchbase ingestion by @daschl http://nitschinger.at/Using-the-Reactor-Processor-for-HighPerformance-TCP ! ● Benefits of using Reactor Processor, TCP and Batching facilities @glaforge — @smaldini / #DV13-rtweb !41
  • 42. Demo
  • 44. Grails — The Age of Asynchronous Fact #1: – HTTP request thread is critical path – Do the barely necessary for fast rendering – If it’s long*, do it in a separate thread @glaforge — @smaldini / #DV13-rtweb !44
  • 45. Grails — The Age of Asynchronous Fact #2: – Creating new Threads needs caution – Context switching hurts performances – Concurrent programming is tricky* @glaforge — @smaldini / #DV13-rtweb !45
  • 46. Grails — The Age of Asynchronous Fact #3: – Burden on your application is never constant – Scaling Up is a good start… – …And Scaling Out is only next @glaforge — @smaldini / #DV13-rtweb !46
  • 47. Grails — The Age of Asynchronous So I have to use background threads ? But using them might lead to issues and headaches ? And what if I really need to scale out ? @glaforge — @smaldini / #DV13-rtweb !47
  • 48. Grails — Reactive Programming Recap • Adding a level of indirection : 
 Driving your application with Events • Laziness is key • Scale up/out by tweaking dispatching @glaforge — @smaldini / #DV13-rtweb !48
  • 49. Grails — The Big Picture Application Service Consumer Service Consumer Publish/Subscribe Events Bus Service Consumer @glaforge — @smaldini / #DV13-rtweb Service Consumer Service Consumer !49
  • 50. Grails — The Big Picture Cloud App Publish/Subscribe App Events Bus App App App @glaforge — @smaldini / #DV13-rtweb !50
  • 51. Introducing  GRAILS-­‐EVENTS  plugin BOOM! worse slide ever™ @glaforge — @smaldini / #DV13-rtweb !51
  • 52. Grails — Origins : Platform-Core plugin • An initiative to provide modern tools for grails development ! • Among them: the Events API • An abstraction used in a few Grails applications today to decouple logic from producers ! • grails-events can be considered as 
 Platform Core Events API 2.0 @glaforge — @smaldini / #DV13-rtweb !52
  • 53. Grails — Why a new plugin ? • New features. And quite a few. – Streaming data, Selectors, Queue ! • Based on a new solid foundation – Reactor – Where Platform-core Events best ideas have leaked ! • Semantic changes – But relatively straightforward migration path @glaforge — @smaldini / #DV13-rtweb !53
  • 54. Grails — Why a new plugin ? • Lightweight, only focused on events ! • Ready to be embedded in a future Grails version • Complete the asynchronous story • Could enable runtime plugin deployment @glaforge — @smaldini / #DV13-rtweb !54
  • 55. Grails — So what Grails Events is about • Grails Apps and Plugins can use Events to: – Listen for plugins/app events – Start simple with in-memory eventing (#uberfastdata) – Do Asynchronous calls (default) – Increase in flexibility if required @glaforge — @smaldini / #DV13-rtweb !55
  • 56. Grails — Installing Grails Events • It’s a binary plugin (!) • Requires Grails 2.2+ repositories  {          //...                mavenRepo  "http://repo.springsource.org/libs-­‐snapshot"          mavenRepo  "http://repo.grails.org/grails/libs-­‐snapshots-­‐local/"   }   ! dependencies  {          compile  'org.grails.plugins:events:1.0.0.BUILD-­‐SNAPSHOT'   }   @glaforge — @smaldini / #DV13-rtweb !56
  • 57. Grails — Semantics: Consumer • A Consumer: – Accepts an Event – Is registered in a Service or Events artifact, or by calling on() – Can be thread safe • Depending on the dispatcher type • Assuming the consumer is not registered more than once @glaforge — @smaldini / #DV13-rtweb !57
  • 58. Grails — Semantics: Selector • A Selector: – Matches an event key – Is paired with a consumer during its registration – Any bean method can be transformed into consumer with @Selector @glaforge — @smaldini / #DV13-rtweb !58
  • 59. Grails — Semantics: Reactor • A Reactor: – Is a dedicated Consumer Registry – Has an assigned Dispatcher – Uses a specific Event Router ! • Usually, if the Dispatcher doesn’t need to be adapted, reuse the default reactor grailsReactor @glaforge — @smaldini / #DV13-rtweb !59
  • 60. Grails — Pattern Examples : Event Driven CQRS http://martinfowler.com/bliki/CQRS.html Save a GORM entity SaveService GORM DB PostProcessingService Insert Record @glaforge — @smaldini / #DV13-rtweb Trigger afterInsert event Consume afterInsert events !60
  • 61. Grails — Pattern Examples : Modular Architecture Core application untouched Trigger ‘request’ event Main Application RequestService Notification Plugin NotificationService Create a decoupled module @glaforge — @smaldini / #DV13-rtweb Consume ‘request’ events !61
  • 62. Grails — Pattern Examples : Background Processing Return immediately Grails Controller REST service Request Service HTTP Request Trigger ‘request’ event (async) Long REST call @glaforge — @smaldini / #DV13-rtweb !62
  • 63. Grails — Sending Events (grails-platform-core) def  user  =  new  User(params).save()   ! event('mailRegistration',  user)       //event('mailRegistration',  user).waitFor()       //event  topic:'mailRegistration',  data:user       //event  topic:'mailRegistration',  data:user,  fork:false       render(view:'sendingRegistrationMail') @glaforge — @smaldini / #DV13-rtweb !63
  • 64. Grails — Sending Events (grails-events) def  user  =  new  User(params).save()   ! event('mailRegistration',  user)                 event('mailRegistration',  user)  {          if(it  ==  ‘end')  {                  cancel()          }   }       Non blocking call to trigger app consumers Do things on each reply Map notation ! //  event  key:  'mailRegistration',  data:  user   ! render(view:  'sendingRegistrationMail') @glaforge — @smaldini / #DV13-rtweb !64
  • 65. Grails — Consuming Events (grails-platform-core) class  UserService{          @grails.events.Listener          def  mailRegistration(User  user)  {                  sendMail  {                          to  user.mail                          subject  "Confirmation"                          html  g.render(template:"userMailConfirmation")                  }          }   !        @grails.events.Listener(topic=  "mailRegistration")          def  mailRegistration2(org.grails.plugin.platform.events.EventMessage  msg)  {                  sendMail{                        to  msg.data.mail                        subject  "Confirmation"                        html  g.render(template:  "userMailConfirmation")                  }          }   } @glaforge — @smaldini / #DV13-rtweb !65
  • 66. Grails — Consuming Events (grails-events) Consume on Selector(method name) class  UserService{              @reactor.spring.annotation.Selector          def  mailRegistration(User  user){                  sendMail{                          to  user.mail                          subject  "Confirmation"                          html  g.render(template:  "userMailConfirmation")                  }          }   Consume on this specific topic !        @reactor.spring.annotation.Selector("mailRegistration")          def  mailRegistration2(reactor.event.Event  msg){                  sendMail{                          to  msg.data.mail                          subject  "Confirmation"                          html  g.render(template:"userMailConfirmation")                  }          }   } @glaforge — @smaldini / #DV13-rtweb Event typed signature to inspect enveloppe (‘headers…) !66
  • 67. Grails — A new Artifact conf/XxxxEvents includes  =  ['default']   Merge with DefaultsEvents ! doWithReactor  =  {          reactor(EventsApi.GRAILS_REACTOR)  {                  on('someTopic')  {                          reply  'test'                                          }                                                                                                        }                                                                                                                                        reactor(‘someGormReactor')  {                                                                                                            dispatcher  =  new  SynchronousDispatcher()                  ext  'gorm',  true                                                                                                                   Build a GroovyEnvironment Reactor Groovy Builders ! Grails extension: accept GORM events                stream  {                          consume  {                                  log.info  "Some  gorm  event  is  flowing  with  data  $it.data"                          }.when(Throwable)  {                                  log.error  "Ow  snap!",  it                          }                                                                                                                                                        }                                                      }                                                                                                                                                         } @glaforge — @smaldini / #DV13-rtweb !67
  • 68. Grails — Reactor awesomeness : Selectors • Listen for arbitrary keys • import static reactor.event.selector.Selectors.* on(T(SpecificClassType))  {   Listen for SpecificClassType                reply  it                                   }                                                                                                 ! Send using right key type event(new  SpecificClassType(),  'data')                                                           ! ! Listen for an URI on(uri(‘/some/{captureIt}'))  {                                                                                          reply  it.headers.captureIt   }                                                                                                                                     ! Send using matching URI event('/some/hourray',  'data')         @glaforge — @smaldini / #DV13-rtweb !68
  • 69. Grails — Reactor awesomeness : Stream API • Reactive Extensions programming style • Avoid callback hell Build a Stream to capture any reply $(‘test’) consumers may reply withStream  {          event(key:  'test',  data:  1)   }.when(Exception,  {   If a consumer fails        log.info  "exception:$it"   }).map  {   Transform result        callExternalService(it)   }.consume('clientKey',  reactor('browser')) Reroute to key ‘clientKey’ on Reactor ‘browser’ @glaforge — @smaldini / #DV13-rtweb !69
  • 70. Grails — Reactor awesomeness: Promise API • Grails 2.3 Promises become a Reactor Promises • Benefits from Dispatcher overriding • Powerful once Combined with Consumers dispatcher(ReactorPromise.PromiseDispatcher)  {          type  =  DispatcherType.RingBuffer          backlog  =  512   } task  {          def  res  =   longProcessing()          render  res   } @glaforge — @smaldini / #DV13-rtweb !70
  • 71. Grails — Reactor awesomeness : Routing • During event dispatching, consumers list is selected • Publish Subscribe is the default • Possible to assign different routing strategy reactor('test1')  {          routingStrategy  'round-­‐robin'          on('test')  {                  reply  '1'   Will reply 1, 2, 1, 2, 1, 2…        }                        on('test')  {                  reply  '2'          }                 } @glaforge — @smaldini / #DV13-rtweb !71
  • 72. Grails — Extensibility ! • Main extension points: – Dispatcher, Selector, Registry, EventRouter, Consumer ! • Metadata in Reactor Events DSL: – ext(‘someExtension’, [ ‘doStuff’: true ]) @glaforge — @smaldini / #DV13-rtweb !72
  • 73. Grails — GORM events • GORM is now an extension – Using ext(‘gorm’, true) on any candidate reactor – Applicable Selectors: simple topic form (beforeInsert...) – A boolean reply is evaluated as a cancel directive reactor('someGormReactor'){          dispatcher  =  new  SynchronousDispatcher()          ext  'gorm',  true   @Selector(reactor  =  'someGormReactor')   }     @ReplyTo   boolean  beforeValidate(Book  b){          false   } @glaforge — @smaldini / #DV13-rtweb !73
  • 74. GRAILS-­‐EVENTS-­‐PUSH  plugin Eventing over HTTP! @glaforge — @smaldini / #DV13-rtweb !74
  • 75. Grails — Pattern Examples : “Realtime” web Push reply to browser: Websocket, SSE, long-polling… Reply a new event ResponseService Browser Return immediately @glaforge — @smaldini / #DV13-rtweb Grails Controller RequestService Trigger async event !75
  • 76. Grails — An elegant solution to browser push • Powered by Atmosphere 2 • Automatically picks an adapted protocol: – WebSockets, ServerSideEvent, Streaming, Polling… • Consumer bridges for server-to-client push • Reactor bridge for client-to-server push • Javascript library @glaforge — @smaldini / #DV13-rtweb !76
  • 77. Grails — Installing Grails Events Push 1. Install Grails Events plugin 2. Install Grails Events Push plugin grails.servlet.version  =  "3.0"   grails.tomcat.nio  =  true   ! Use a “long-connection” friendly tomcat configuration grails.project.dependency.resolution  =  {          repositories  {          //...                  mavenRepo  "https://oss.sonatype.org/content/repositories/snapshots"          }                                            dependencies  {                                  //...                                                    compile  'org.grails.plugins:events:1.0.0.BUILD-­‐SNAPSHOT'          }                                                                                            plugins  {                                                                                            //...                                                                                                    runtime  ":jquery:1.10.2"                                                                                                                                  runtime  ":events-­‐push:1.0.0.BUILD-­‐SNAPSHOT"                                                }   } @glaforge — @smaldini / #DV13-rtweb !77
  • 78. Grails — grails-events-push Lifecycle 1 - Handshake Browser EventsPushHandler Adapt Protocol and Open new persistent connection @glaforge — @smaldini / #DV13-rtweb !78
  • 79. Grails — grails-events-push Lifecycle 2 - Register Consumer registered on all Reactor with ‘browser’ extension enabled Browser Reactor(s) Bridge a Client Consumer with a remote Reactor Consumer @glaforge — @smaldini / #DV13-rtweb !79
  • 80. Grails — grails-events-push Lifecycle 3 - Notify RequestService consumes on matching Selector within the ‘browser’ Reactor Browser ‘browser’ Reactor RequestService Notify any key @glaforge — @smaldini / #DV13-rtweb !80
  • 81. Grails — grails-events-push Lifecycle 4 - Consume Notify ‘browser’ enabled Reactor and match key Browser Reactor(s) ResponseService Push event (WS, SSE…) @glaforge — @smaldini / #DV13-rtweb !81
  • 82. Grails — Generating Simple Browsers bridges includes  =  'push'   ! Conventional name to override ‘browser’ reactor doWithReactor  =  {          reactor('browser')  {                  ext  'browser',  [                          'control',                          'move',                          'fire',                          'leave'                  ]          }          reactor(‘grailsReactor')  {                  ext  'browser',  ['sleepBrowser']   Bridge browser to these reactor consumers $(‘control),… !                stream(‘sleepBrowser')  {                          filter  {                                    it.data  ==  'no'                          }                  }          }   } @glaforge — @smaldini / #DV13-rtweb Bridge browser to this reactor consumer $(‘sleepBrowser) Prevent data ‘no’ to be dispatched to browser bridges !82
  • 83. Grails — React on server side events Inject grailsEvents.js (requires resources plugin) Create a connection between the browser and the current Grails app Listen for $(‘afterInsert’) events @glaforge — @smaldini / #DV13-rtweb !83
  • 84. Grails — Generating Advanced Browsers bridges includes  =  ['push']   ! Include PushEvents (configure a reactor for events from Browsers) doWithReactor  =  {          reactor(‘grailsReactor')  {                  ext  'gorm',  true                            ext  'browser',  [                                                                                                                                        'test':  true,                      'afterInsert':  [                                        browserFilter:  {m,  r  -­‐>  true  }                                                                                            ],                                                                                                                                                            (R("sampleBro-­‐.*"))  :  true,                  ]                                                                                                                                                      }                                                                                                                                                              reactor(EventsPushConstants.FROM_BROWSERS)  {                  ext  'browser',  [R("sampleBro-­‐.*")]                                                                                    }                                                                                                             }   Listen on GORM events Extension to bridge Browsers consumers to Server-side pair Events are only routed, from Browsers to bridged Browsers @glaforge — @smaldini / #DV13-rtweb Override “From Browsers” reactor and bridge consumers !84
  • 85. Grails — The Bad Stuff • events-si : Events API on top of Spring Integration – Not here (just) yet ! • events-vertx : Abandoned experiment – Working around Distributed Reactor ! • Stream DSL could be optimized – Reducing the number of objects @glaforge — @smaldini / #DV13-rtweb !85
  • 86. Grails — Roadmap • events: – Document, especially for Migration from Platform Core – Stick with latest awesome features from Reactor • Still Many API to expose: Processors, Buffer, TCP, Queues, Sequencer… ! • events-push -> events-atmosphere : – Add support for replyTo – extract to standalone module : reactor-atmosphere @glaforge — @smaldini / #DV13-rtweb !86
  • 87. Grails — Roadmap • events-sockjs: – Involves Reactor work here ! • events-si: – Supports new events plugin ! • events-xx: – The plugin where you are the hero @glaforge — @smaldini / #DV13-rtweb !87
  • 88. Demo
  • 90. Groovy, Reactor, Grails and the realtime web • Embrace modern reactive architectures with Groovy, Reactor and Grails! • Groovy is a versatile language, that enables development of concise and functional oriented applications • Reactor fuels your asynchronous and reactive applications with its ultra fast dispatching engine and non-blocking model. • Grails supports your today's and tomorrow's web app design, tooled with the right plugins you are prepared for responsive and interactive applications @glaforge — @smaldini / #DV13-rtweb !90