Vert.x and RxJava
@petermd
eclipsecon 2014
BIO
- CTO at Donnerwood Media
- Social / Mobile Software Developer
- High-Performance Servers
- Telcos, Gaming, Startups
- Vert.x
- mod-rxvertx
- github.com/petermd

REACTIVE
programming
Fork()
for (;;) { fd = accept(listenfd, ...);if ( (pid = fork()) == 0 ) { close(listenfd);/* Process request */exit(0); } close(fd); }
CONCURRENCY
C10
poll()
do { rc=poll(fds, nfds, timeout); current_size = nfds; for (i = 0; i < current_size; i++) { if(fds[i].revents == 0) continue; rc = recv(fds[i].fd, buffer, sizeof(buffer), 0); if (rc < 0) {/* Not ready yet */ } ./* Do something */ . } while(TRUE);
CONCURRENCY
C100
ASYNC PROGRAMMING IS
HARD
PROTO
COLS
ASYNC PROGRAMMING IS
UGLY
Error Propogation
fs.readdir(source, function(err, files) {
if(err){
console.log('Error finding files: '+err)
}else{
files.forEach(function(filename,fileIndex){
console.log(filename)
gm(source+filename).size(function(err,values){
if(err){
console.log('Error identifying file size: '+err)
}else{
console.log(filename+' : '+values)
aspect=(values.width/values.height)
widths.forEach(function(width,widthIndex){
height=Math.round(width/aspect)
console.log('resizing '+filename+'to '+height+'x'+height)
this
.resize(width,height)
.write(destination+'w'+width+'_'+filename,function(err) {
if(err)
console.log('Error writing file: '+err)
})
}.bind(this))
}
})
})
}
})
CHECK EVERYTHING
'cos if you think handling errors is hard
(not handling errors is worse)

GOTO ERR;
handling non errors isn't great either
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
WHAT ABOUT THREADS?
- light-weight
- linear
- exceptions
- multi-core
CONCURRENCY
C1k
FUTURE IS REACTIVE
-
them > us
- responsive
- resilient
- ..need a better model
ReacTIVE EXTENSIONS
- Part of .NET
- Netflix adapted for Server
- Other ports
- RxJS, RxCpp,Rx.rb,Rx.py
WHAT IS RX?
"a library for composing asynchronous and event-based programs by using observable sequences"
OBSERVABLE
- Iterable but Async
- Observer
- Operators
- Subscribers
- Reliable Error Propagation
- Zero or More elements
OBSERVER
interface Observer<T> {void onNext(T value);void onCompleted();void onError(Throwable t);}
OPERATORS
-
map
-
flatMap
-
concat
-
zip / join / reduce
-
buffer / window
- rescue
- ...
EXAMPLES
Simple Sequence
myStringService.fetch().subscribe { v -> println("Got: "+v) }
EXAMPLES
Transform
myStringService.fetch().map { v -> v.toLowerCase() }.subscribe(...)
EXAMPLES
TRANSFORM ONLINE
myStringService.fetch().flatMap { v -> myTranslationService.translate(v) }.subscribe(...)
EXAMPLES
MERGE
Observable<String> s=myStringService.fetch().publish()Observable<String> lc=s.map { v -> v.toLowerCase() }Observable<String> tr=s.flatMap { v -> myTranslateService.translate(v) }Observable.zip(lc,tr,{ word, translated -> { return word+"="+translated } }).subscribe({ v -> println(v) },{ e -> println("ERROR:"+e) })
MOD-RXVertX
-
Observable
- void async(...,Handler<T>)
- Obserable<T> observe(...)
- Read/Write Streams
- Useful Functions
VERTX EXAMPLE
EVENT BUS
RxEventBus eb=new RxEventBus(vertx.eventBus());eb.<String>registerHandler("ping").subscribe( (RxMessage<String>) (m) -> {m.reply("pong")})eb.send("ping","yolo").subscribe((RxMessage<String>)(m) -> {out.println("got:"+m.body());});
PATTERNS
- PROCESS
- STREAM
- FILTER
- RENDER
- COMMAND
-
RETRY
- FLOW CONTROL
PROCESS
HTTP SERVER
RxHttpServer server=new RxHttpServer(...);server.http().subscribe((RxHttpServerRequest)(req) -> {// Handle request and request.toObservable() inside// a new Observable});
PROCESS
HTTPCLIENT
RxHttpClient client=new RxHttpClient(...);client.getNow("/someurl).flatMap(parseResponse).map(handleResponse)// Subscription used to map output to response.subscribe(...)
STREAM
CONVERSATION
eb.send("guest","you'll have tea").flatMap((RxMessage)(resp) -> {return resp.reply("ah you will");}).flatMap((RxMessage)(resp) -> {return resp.reply("pour-tea");}).subscribe(...)
STREAM
PIPELINE
rx.<String>observeStream("pint",1).map((Func1<RxStream,Integer>)(s) -> {// request next blocks.next(...);// forward current blockreturn s.value();}).subscribe(...)
FILTER
Observable<HttpServerRequest> req;req=Observable.just(req).filter(checkValid) // remove request if handled eg redirect.map(checkAuth) // map it if just adding data.flatMap(lookupAuth) // flatMap if you need a remote call.map(..process request..).subscribe(renderResponse,renderError)
RENDER
BASIC TYPES
/** Render string */ public static void render(HttpServerResponse resp, String value) { resp .headers().add("Content-Type","text/plain;charset=UTF8"); resp .setChunked(true) .end(value); }void render(HttpServerResponse resp, JsonObject value) {..}void renderErr(HttpServerResponse resp, int code, String msg) {..}
RENDER
OBSERVABLE
void render(HttpServerResponse resp, Observable ob) {// map value + error to renderer// completed without value -> response already sent}HttpSupport.render(resp,process);
COMMAND
HTTP UPLOAD
Observable<Buffer> in=request.toObservable();HttpCommand<> cmd=new HttpCommand(request,in.map(..));Observable<HttpCommand> cmd=HttpSupport.waitFor(cmd);
COMMAND
JSON Request
/** Return Observable<HttpCommand<JsonObject>> */
public static Observable jsonRequest(RxHttpServerRequest request) {
HttpCommand req=
new HttpCommand(
request,
request
.asObservable()
.reduce(mergeBuffers)
.map(toJson));
return waitFor(req);
}
COMMAND
USAGE
Obserable .just(request) .flatMap(HttpSupport.jsonRequest) .map((HttpCommand)(cmd) -> {// cmd.body is the JsonObject })
RETRY
eventBus.observeSend("db",request).retry(2).subscribe(...)
FLOW CONTROL
FAST PRODUCER
Observable<String> firehose=rx.<String>observeStream("twitter","*").map((RxStream)(s) -> { s.next(..); return s.value(); }).map((String)(s) -> { ..render.. })RxSupport.stream(firehose,output);
FLOW CONTROL
USING REGULATOR
Regulator reg=new Regulator();Observable<String> firehose=rx.<String>observeStream("twitter","*").lift(reg).map((RxStream)(s) -> { s.next(..); return s.value(); }).map((String)(s) -> { ..render.. })reg.stream(firehose,output);
SUMMARY
- Async Programming is complex
- RxJava gives you
- Readable programs
- Reliable error handling
- Re-usable patterns
- http://github.com/vert-x/mod-rxvertx
- RxJava 0.17.1
THANK YOU
Q&A
Copy of Vert.x and RxJava (eclipsecon)
By Denis Stoyanov
Copy of Vert.x and RxJava (eclipsecon)
Talk on VertX and RxJava from eclipsecon2014
- 2,217
