SlideShare a Scribd company logo
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
8 - 24 minute delay
± 30 min. round trip
Web
• DNS
• Redirect
• Download HTML
• Download CSS + JS + Images
• Download more CSS + JS + Images
• ….
Ordering a pizza
• Several hours per page
• About 8 pages per order
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Thread.setName(“Bob”);
String token =
getGitHubToken("https://github.com/login",<params>);
• Connect TCP
• Encryption handshake
• Push request data through socket
• … wait …
• Pull data from the socket
• Assemble and return the result
Non Blocking I/O for Everyone with RxJava
Blink of an eye
100ms
Time
Network latency: milliseconds
Application instruction: microseconds
Hardware instructions: nanoseconds
String token =
getGitHubToken("https://github.com/login",<params>);
=
#WRONG
Non Blocking I/O for Everyone with RxJava
Non Blocking For Everyone
with RxJava
@lyaruu
Frank Lyaruu
CTO Dexels
Non Blocking in Action 27
https://webtide.com/async-rest
So why are we still writing blocking code?
! It works pretty well in monoliths
! CPU and memory is cheap
! Networks are reliable and fast
! Writing non blocking code is hard
28
Writing non blocking code is rough
29
Servlet API
30
Non Blocking I/O Servlet API 3.1
31
A Blocking Echo Servlet 32
public class BlockingServlet extends HttpServlet {
private static final int BUFFER_SIZE = 1024;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
byte[] buffer = new byte[BUFFER_SIZE];
while (true) {
int read = request.getInputStream().read(buffer, 0, BUFFER_SIZE);
if (read < 0)
break;
response.getOutputStream().write(buffer, 0, read);
}
}
}
A Non Blocking Echo Servlet 33
public class NonBlockingServlet extends HttpServlet {
private static final int BUFFER_SIZE = 1024;
@Override
protected void service(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
{
AsyncContext asyncContext = request.startAsync(request, response);
asyncContext.setTimeout(0);
Echoer echoer = new Echoer(asyncContext);
request.getInputStream().setReadListener(echoer);
response.getOutputStream().setWriteListener(echoer);
}
private class Echoer implements ReadListener, WriteListener
{
private final byte[] buffer = new byte[BUFFER_SIZE];
private final AsyncContext asyncContext;
private final ServletInputStream input;
private final ServletOutputStream output;
private boolean complete;
private Echoer(AsyncContext asyncContext) throws IOException
{
this.asyncContext = asyncContext;
this.input = asyncContext.getRequest().getInputStream();
this.output = asyncContext.getResponse().getOutputStream();
}
@Override
public void onDataAvailable() throws IOException
{
while (input.isReady())
{
int read = input.read(buffer);
output.write(buffer, 0, read);
if (!output.isReady())
return;
}
if (input.isFinished())
{
complete = true;
asyncContext.complete();
}
}
@Override
public void onAllDataRead() throws IOException {}
@Override
public void onWritePossible() throws IOException
{
if (input.isFinished())
{
if (!complete)
asyncContext.complete();
}
else
{
onDataAvailable();
}
}
@Override
public void onError(Throwable failure)
{
failure.printStackTrace();
}
}
}
Maybe something simpler 34
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
AsyncContext asyncContext = request.startAsync(request, response);
final ServletOutputStream out = resp.getOutputStream();
final byte[] buf = new byte[1024];
final FileInputStream file = …;
out.setWriteListener(new WriteListener() {
@Override
public void onWritePossible() throws IOException {
while(out.isReady()) {
int len = file.read(buf);
if(len<0) {
return;
}
out.write(buf, 0, len);
}
}
});
}
35
Bob
36
Developer
Node.js 37
var server = http.createServer(function (req, res) {
req.pipe(res);
});
Node.js 38
var server = http.createServer(function (req, res) {
req.pipe(res);
});
A pipe… 39
Reactive Programming
40
Programming pipes
ReactiveX
41
Polyglot
RxJava RxScala RxJS RxPHP
Observable<T>
42
Will push zero or more items of type T
Followed by a ‘completed’ message
(or an error…)
RxJava Quick Intro 43
Observable.<String>just("Ouagadougou","Dakar","Accra","Rabat")
.subscribe(item->System.err.println(item));
Ouagadougou
Dakar
Accra
Rabat
RxJava Quick Intro 44
Observable.range(0, 1000)
.subscribe(item->System.err.println(item));
0
1
2
3
4
5
6
…
998
999
RxJava Quick Intro 45
Observable.range(0, 1000)
.skip(10)
.take(10)
.subscribe(item->System.err.println(item));
10
11
12
13
14
15
16
17
18
19
RxJava Quick Intro 46
Bytes.fromFile("citiesafrica.xml")
.lift(XML.parse())
.subscribe(item->System.err.println(item));
<cities>
<africa>
<city name="Lusaka"/>
<city name="Harare"/>
<city name="Kigali"/>
</africa>
</cities>
START_DOCUMENT
START_ELEMENT cities {}
START_ELEMENT africa {}
START_ELEMENT city {name=Lusaka}
END_ELEMENT city
START_ELEMENT city {name=Harare}
END_ELEMENT city
START_ELEMENT city {name=Kigali}
END_ELEMENT city
END_ELEMENT africa
END_ELEMENT cities
END_DOCUMENT
RxJava Quick Intro 47
Bytes.fromFile("citiesafrica.xml")
.lift(XML.parse())
.filter(e->e.getType()==XmlEventTypes.START_ELEMENT)
.map(e->e.getAttributes().get("name"))
.subscribe(item->System.err.println(item));
<cities>
<africa>
<city name="Lusaka"/>
<city name="Harare"/>
<city name="Kigali"/>
</africa>
</cities>
Lusaka
Harare
Kigali
static Observable<byte[]> createSourceObservable(HttpServletRequest req);
static Subscriber<byte[]> createSink(HttpServletResponse resp);
protected void doPost(HttpServletRequest req, final HttpServletResponse resp) {
createSourceObservable(req)
.subscribe(createSink(resp));
}
RxJava Quick Intro
Reactive API’s
49
A Blocking API
public static Double temperatureInCity(String city) {
return Double.parseDouble(HTTPClient
.get("http://api.weather.org/weather?q="+city)
.toXml()
.getContent("temperature"));
}
For consumers:
Double temperature = temperatureInCity("Tripoli");
Convert to Reactive
public Observable<Double> temperatureInCity(String city) {
return Observable.just(
Double.parseDouble(HTTPClient
.get("http://api.weather.org/weather?q="+city)
.toXml()
.getContent("temperature")
));
}
Non Blocking I/O for Everyone with RxJava
Sort of…
Double temp =
temperatureInCity(“Cairo”).blockingFirst();
updateTemperatureUI(temp);
This code is still just as blocking
But now the consumer and producer have independent
threading
Use a Non Blocking HTTP Client
public static Observable<Double> temperatureInCity(String city) {
return HTTP.get("http://api.weather.org/weather?q="+city)
.subscribeOn(Schedulers.io())
.lift(XML.parse())
.filter(e->e.getType()==XmlEventTypes.START_ELEMENT)
.filter(e->e.getText().equals("temperature"))
.first()
.map(xml->Double.parseDouble(xml.getAttributes().get("value")));
}
Add a Cache
public Observable<Double> temperatureInCity(String city) {
Double temperature = temperatureCache.get(city);
if(temperature!=null) {
return Observable.just(temperature);
}
return HTTP.get("http://api.weather.org/weather?q="+city)
.subscribeOn(Schedulers.io())
.lift(XML.parse())
.filter(e->e.getType()==XmlEventTypes.START_ELEMENT)
.filter(e->e.getText().equals("temperature"))
.first()
.map(xml->Double.parseDouble(xml.getAttributes().get("value")))
.doOnNext(temperature->temperatureCache.put(city,temperature));
}
Non Blocking Client
Blocking:
Double temp = temperatureInCity(“Cairo").toBlocking().first();
updateTemperatureUI(temp);
Non blocking:
temperatureInCity(“Nairobi”)
.observeOn(UISchedulers.uiThread())
.subscribe(d->updateTemperatureUI(d));
Challenges
57
Back pressure
58
Back pressure
59
Operation
A Blocking Echo Servlet 60
public class BlockingServlet extends HttpServlet {
private static final int BUFFER_SIZE = 1024;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
byte[] buffer = new byte[BUFFER_SIZE];
while (true) {
int read = request.getInputStream().read(buffer, 0, BUFFER_SIZE);
if (read < 0)
break;
response.getOutputStream().write(buffer, 0, read);
}
}
}
Back pressure
61
! Observable: No back pressure
! Flowable: Back pressure
RxJava back pressure 62
Bytes.fromNetwork(“something_huge.xml”)
.lift(XML.parse())
.filter(e->e.getType()==XmlEventTypes.START_ELEMENT)
.map(e->e.getAttributes().get("name"))
.subscribe(item->doSomethingComplicated(item));
Back pressure
63
Operation
Back pressure
64
Operation
Memory Consumption
65
! Much better
! … or much worse
Error Handling
66
! Some patterns don’t work any more
! Requires some thought
Error handling 67
Servlet.handlePost()
.lift(XML.parse())
.subscribe(item->sendSomeWhere(item));
<cities>
<africa>
<city name="Lusaka"/>
<city name="Harare"/>
<city name="Kigali"/>
</cities>
START_DOCUMENT
START_ELEMENT cities {}
START_ELEMENT africa {}
START_ELEMENT city {name=Lusaka}
END_ELEMENT city
START_ELEMENT city {name=Harare}
END_ELEMENT city
START_ELEMENT city {name=Kigali}
END_ELEMENT city
END_ELEMENT africa
PARSE_ERROR
Non Blocking is not faster
68
! It is about utilising threads better
! If thread utilisation is not an issue, it
will perform similarly
Thoughts
69
! RxJava is lightweight and easy to add to existing
software
! Pleasant programming model
! Makes non blocking I/O bearable
! Can be used incrementally
Conclusions
70
! Threads are expensive
! Everything keeps getting faster except the speed of light
! Micro services
! Blocking code misbehaves under pressure
! The price of blocking communication will keep going up
I believe that, in time, some non blocking code is inevitable
Frank @Lyaruu dexels.com

Dexels frank@dexels.com
Please rate!

More Related Content

What's hot (20)

PDF
Forgive me for i have allocated
Tomasz Kowalczewski
 
PPTX
Avoiding Callback Hell with Async.js
cacois
 
PDF
Reactive Fault Tolerant Programming with Hystrix and RxJava
Matt Stine
 
PDF
AWS Java SDK @ scale
Tomasz Kowalczewski
 
PDF
Intro to RxJava/RxAndroid - GDG Munich Android
Egor Andreevich
 
PDF
Reactive server with netty
Dmitriy Dumanskiy
 
PDF
Reactive programming on Android
Tomáš Kypta
 
PDF
RxJava on Android
Dustin Graham
 
PDF
RxJava applied [JavaDay Kyiv 2016]
Igor Lozynskyi
 
PDF
Callbacks and control flow in Node js
Thomas Roch
 
PDF
Concurrency Utilities in Java 8
Martin Toshev
 
PDF
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
PPTX
Reactive programming with RxAndroid
Savvycom Savvycom
 
PPTX
RxJS and Reactive Programming - Modern Web UI - May 2015
Ben Lesh
 
PPT
Reactive programming with examples
Peter Lawrey
 
PDF
Reactive programming on Android
Tomáš Kypta
 
PDF
Introduction to Retrofit and RxJava
Fabio Collini
 
PDF
Practical RxJava for Android
Tomáš Kypta
 
PPTX
Real world functional reactive programming
Eric Polerecky
 
PDF
The Future of Futures - A Talk About Java 8 CompletableFutures
Haim Yadid
 
Forgive me for i have allocated
Tomasz Kowalczewski
 
Avoiding Callback Hell with Async.js
cacois
 
Reactive Fault Tolerant Programming with Hystrix and RxJava
Matt Stine
 
AWS Java SDK @ scale
Tomasz Kowalczewski
 
Intro to RxJava/RxAndroid - GDG Munich Android
Egor Andreevich
 
Reactive server with netty
Dmitriy Dumanskiy
 
Reactive programming on Android
Tomáš Kypta
 
RxJava on Android
Dustin Graham
 
RxJava applied [JavaDay Kyiv 2016]
Igor Lozynskyi
 
Callbacks and control flow in Node js
Thomas Roch
 
Concurrency Utilities in Java 8
Martin Toshev
 
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
Reactive programming with RxAndroid
Savvycom Savvycom
 
RxJS and Reactive Programming - Modern Web UI - May 2015
Ben Lesh
 
Reactive programming with examples
Peter Lawrey
 
Reactive programming on Android
Tomáš Kypta
 
Introduction to Retrofit and RxJava
Fabio Collini
 
Practical RxJava for Android
Tomáš Kypta
 
Real world functional reactive programming
Eric Polerecky
 
The Future of Futures - A Talk About Java 8 CompletableFutures
Haim Yadid
 

Viewers also liked (14)

PDF
Rx-Java - Como compor sua aplicacao com Observables
lokimad
 
PDF
Real-world applications of the Reactive Extensions
Jonas Chapuis
 
PDF
Rxjava meetup presentation
Guillaume Valverde
 
PDF
Code Learn Share
Florina Muntenescu
 
PDF
A Journey Through MV Wonderland
Florina Muntenescu
 
PDF
Thirty months of microservices. Stairway to heaven or highway to hell
Sander Hoogendoorn
 
PPTX
Aliyah: Looking for a hi-tech job in Israel
Hayim Makabee
 
PDF
Code lifecycle in the jvm - TopConf Linz
Ivan Krylov
 
PPTX
Welcome to rx java2
Paresh Dudhat
 
PDF
Futures and Rx Observables: powerful abstractions for consuming web services ...
Chris Richardson
 
PPTX
MVVM and RxJava – the perfect mix
Florina Muntenescu
 
PDF
Java 8 Stream API and RxJava Comparison
José Paumard
 
PDF
Saving lives with rx java
Shahar Barsheshet
 
PPTX
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Rx-Java - Como compor sua aplicacao com Observables
lokimad
 
Real-world applications of the Reactive Extensions
Jonas Chapuis
 
Rxjava meetup presentation
Guillaume Valverde
 
Code Learn Share
Florina Muntenescu
 
A Journey Through MV Wonderland
Florina Muntenescu
 
Thirty months of microservices. Stairway to heaven or highway to hell
Sander Hoogendoorn
 
Aliyah: Looking for a hi-tech job in Israel
Hayim Makabee
 
Code lifecycle in the jvm - TopConf Linz
Ivan Krylov
 
Welcome to rx java2
Paresh Dudhat
 
Futures and Rx Observables: powerful abstractions for consuming web services ...
Chris Richardson
 
MVVM and RxJava – the perfect mix
Florina Muntenescu
 
Java 8 Stream API and RxJava Comparison
José Paumard
 
Saving lives with rx java
Shahar Barsheshet
 
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Ad

Similar to Non Blocking I/O for Everyone with RxJava (20)

PPTX
Everything you wanted to know about writing async, concurrent http apps in java
Baruch Sadogursky
 
PPTX
Presentation: Everything you wanted to know about writing async, high-concurr...
Baruch Sadogursky
 
PPTX
Think async
Bhakti Mehta
 
PPTX
Don't Wait! Develop Responsive Applications with Java EE7 Instead
WASdev Community
 
ODP
How to bake reactive behavior into your Java EE applications
Ondrej Mihályi
 
PDF
Asynchronous, Event-driven Network Application Development with Netty
Ersin Er
 
PDF
What is NodeJS - Why Should You Care
gjj391
 
PDF
Tech Webinar: AUMENTARE LA SCALABILITÀ DELLE WEB APP CON SERVLET 3.1 ASYNC I/O
Codemotion
 
DOCX
[Type text]ECET465Project 2Project Assignment 2 Building a Mul.docx
hanneloremccaffery
 
PDF
Caching. api. http 1.1
Artjoker Digital
 
PDF
Async Http Client for Java and Scripting Language
jfarcand
 
DOCX
Project Assignment 2 Building a Multi-Threaded Web ServerThis pro.docx
kacie8xcheco
 
PDF
Efficient HTTP Apis
Adrian Cole
 
PDF
Non-blocking I/O, Event loops and node.js
Marcus Frödin
 
DOCX
692015 programming assignment 1 building a multi­threaded w
smile790243
 
PDF
Asynchronous PHP and Real-time Messaging
Steve Rhoades
 
PDF
Netty: asynchronous data transfer
Victor Cherkassky
 
PDF
A java servers
vibrantuser
 
ODP
Servlet 3.1 Async I/O
Simone Bordet
 
PPT
A java servers
vibrantuser
 
Everything you wanted to know about writing async, concurrent http apps in java
Baruch Sadogursky
 
Presentation: Everything you wanted to know about writing async, high-concurr...
Baruch Sadogursky
 
Think async
Bhakti Mehta
 
Don't Wait! Develop Responsive Applications with Java EE7 Instead
WASdev Community
 
How to bake reactive behavior into your Java EE applications
Ondrej Mihályi
 
Asynchronous, Event-driven Network Application Development with Netty
Ersin Er
 
What is NodeJS - Why Should You Care
gjj391
 
Tech Webinar: AUMENTARE LA SCALABILITÀ DELLE WEB APP CON SERVLET 3.1 ASYNC I/O
Codemotion
 
[Type text]ECET465Project 2Project Assignment 2 Building a Mul.docx
hanneloremccaffery
 
Caching. api. http 1.1
Artjoker Digital
 
Async Http Client for Java and Scripting Language
jfarcand
 
Project Assignment 2 Building a Multi-Threaded Web ServerThis pro.docx
kacie8xcheco
 
Efficient HTTP Apis
Adrian Cole
 
Non-blocking I/O, Event loops and node.js
Marcus Frödin
 
692015 programming assignment 1 building a multi­threaded w
smile790243
 
Asynchronous PHP and Real-time Messaging
Steve Rhoades
 
Netty: asynchronous data transfer
Victor Cherkassky
 
A java servers
vibrantuser
 
Servlet 3.1 Async I/O
Simone Bordet
 
A java servers
vibrantuser
 
Ad

More from Frank Lyaruu (7)

PDF
Too young to quit, too old to change
Frank Lyaruu
 
PDF
Embracing Database Diversity with Kafka and Debezium
Frank Lyaruu
 
PDF
Scripting Languages in OSGi
Frank Lyaruu
 
PDF
ApacheCon Core: Service Discovery in OSGi: Beyond the JVM using Docker and Co...
Frank Lyaruu
 
PDF
Developing Like There's No Tomorrow
Frank Lyaruu
 
PDF
Service Discovery in OSGi: Beyond the JVM using Docker and Consul
Frank Lyaruu
 
PPT
Deploying OSGi on an Army of CubieTrucksSendrato powerpoint
Frank Lyaruu
 
Too young to quit, too old to change
Frank Lyaruu
 
Embracing Database Diversity with Kafka and Debezium
Frank Lyaruu
 
Scripting Languages in OSGi
Frank Lyaruu
 
ApacheCon Core: Service Discovery in OSGi: Beyond the JVM using Docker and Co...
Frank Lyaruu
 
Developing Like There's No Tomorrow
Frank Lyaruu
 
Service Discovery in OSGi: Beyond the JVM using Docker and Consul
Frank Lyaruu
 
Deploying OSGi on an Army of CubieTrucksSendrato powerpoint
Frank Lyaruu
 

Recently uploaded (20)

PPTX
法国巴黎第二大学本科毕业证{Paris 2学费发票Paris 2成绩单}办理方法
Taqyea
 
PDF
Enhancing Parental Roles in Protecting Children from Online Sexual Exploitati...
ICT Frame Magazine Pvt. Ltd.
 
PPTX
PHIPA-Compliant Web Hosting in Toronto: What Healthcare Providers Must Know
steve198109
 
PDF
BRKACI-1001 - Your First 7 Days of ACI.pdf
fcesargonca
 
PDF
FutureCon Seattle 2025 Presentation Slides - You Had One Job
Suzanne Aldrich
 
PPTX
04 Output 1 Instruments & Tools (3).pptx
GEDYIONGebre
 
PPTX
L1A Season 1 ENGLISH made by A hegy fixed
toszolder91
 
PDF
Cleaning up your RPKI invalids, presented at PacNOG 35
APNIC
 
PDF
Top 10 Testing Procedures to Ensure Your Magento to Shopify Migration Success...
CartCoders
 
DOCX
Custom vs. Off-the-Shelf Banking Software
KristenCarter35
 
PDF
BRKSP-2551 - Introduction to Segment Routing.pdf
fcesargonca
 
PPTX
Lec15_Mutability Immutability-converted.pptx
khanjahanzaib1
 
PPTX
Presentation3gsgsgsgsdfgadgsfgfgsfgagsfgsfgzfdgsdgs.pptx
SUB03
 
PDF
Digital burnout toolkit for youth workers and teachers
asociatiastart123
 
PPTX
Orchestrating things in Angular application
Peter Abraham
 
PDF
Boardroom AI: The Next 10 Moves | Cerebraix Talent Tech
ssuser73bdb11
 
PPTX
Networking_Essentials_version_3.0_-_Module_5.pptx
ryan622010
 
PDF
BRKACI-1003 ACI Brownfield Migration - Real World Experiences and Best Practi...
fcesargonca
 
PPTX
西班牙巴利阿里群岛大学电子版毕业证{UIBLetterUIB文凭证书}文凭复刻
Taqyea
 
PDF
The Internet - By the numbers, presented at npNOG 11
APNIC
 
法国巴黎第二大学本科毕业证{Paris 2学费发票Paris 2成绩单}办理方法
Taqyea
 
Enhancing Parental Roles in Protecting Children from Online Sexual Exploitati...
ICT Frame Magazine Pvt. Ltd.
 
PHIPA-Compliant Web Hosting in Toronto: What Healthcare Providers Must Know
steve198109
 
BRKACI-1001 - Your First 7 Days of ACI.pdf
fcesargonca
 
FutureCon Seattle 2025 Presentation Slides - You Had One Job
Suzanne Aldrich
 
04 Output 1 Instruments & Tools (3).pptx
GEDYIONGebre
 
L1A Season 1 ENGLISH made by A hegy fixed
toszolder91
 
Cleaning up your RPKI invalids, presented at PacNOG 35
APNIC
 
Top 10 Testing Procedures to Ensure Your Magento to Shopify Migration Success...
CartCoders
 
Custom vs. Off-the-Shelf Banking Software
KristenCarter35
 
BRKSP-2551 - Introduction to Segment Routing.pdf
fcesargonca
 
Lec15_Mutability Immutability-converted.pptx
khanjahanzaib1
 
Presentation3gsgsgsgsdfgadgsfgfgsfgagsfgsfgzfdgsdgs.pptx
SUB03
 
Digital burnout toolkit for youth workers and teachers
asociatiastart123
 
Orchestrating things in Angular application
Peter Abraham
 
Boardroom AI: The Next 10 Moves | Cerebraix Talent Tech
ssuser73bdb11
 
Networking_Essentials_version_3.0_-_Module_5.pptx
ryan622010
 
BRKACI-1003 ACI Brownfield Migration - Real World Experiences and Best Practi...
fcesargonca
 
西班牙巴利阿里群岛大学电子版毕业证{UIBLetterUIB文凭证书}文凭复刻
Taqyea
 
The Internet - By the numbers, presented at npNOG 11
APNIC
 

Non Blocking I/O for Everyone with RxJava

  • 6. 8 - 24 minute delay
  • 7. ± 30 min. round trip
  • 8. Web • DNS • Redirect • Download HTML • Download CSS + JS + Images • Download more CSS + JS + Images • ….
  • 9. Ordering a pizza • Several hours per page • About 8 pages per order
  • 18. • Connect TCP • Encryption handshake • Push request data through socket • … wait … • Pull data from the socket • Assemble and return the result
  • 20. Blink of an eye 100ms
  • 21. Time Network latency: milliseconds Application instruction: microseconds Hardware instructions: nanoseconds
  • 23. =
  • 26. Non Blocking For Everyone with RxJava @lyaruu Frank Lyaruu CTO Dexels
  • 27. Non Blocking in Action 27 https://webtide.com/async-rest
  • 28. So why are we still writing blocking code? ! It works pretty well in monoliths ! CPU and memory is cheap ! Networks are reliable and fast ! Writing non blocking code is hard 28
  • 29. Writing non blocking code is rough 29
  • 31. Non Blocking I/O Servlet API 3.1 31
  • 32. A Blocking Echo Servlet 32 public class BlockingServlet extends HttpServlet { private static final int BUFFER_SIZE = 1024; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { byte[] buffer = new byte[BUFFER_SIZE]; while (true) { int read = request.getInputStream().read(buffer, 0, BUFFER_SIZE); if (read < 0) break; response.getOutputStream().write(buffer, 0, read); } } }
  • 33. A Non Blocking Echo Servlet 33 public class NonBlockingServlet extends HttpServlet { private static final int BUFFER_SIZE = 1024; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AsyncContext asyncContext = request.startAsync(request, response); asyncContext.setTimeout(0); Echoer echoer = new Echoer(asyncContext); request.getInputStream().setReadListener(echoer); response.getOutputStream().setWriteListener(echoer); } private class Echoer implements ReadListener, WriteListener { private final byte[] buffer = new byte[BUFFER_SIZE]; private final AsyncContext asyncContext; private final ServletInputStream input; private final ServletOutputStream output; private boolean complete; private Echoer(AsyncContext asyncContext) throws IOException { this.asyncContext = asyncContext; this.input = asyncContext.getRequest().getInputStream(); this.output = asyncContext.getResponse().getOutputStream(); } @Override public void onDataAvailable() throws IOException { while (input.isReady()) { int read = input.read(buffer); output.write(buffer, 0, read); if (!output.isReady()) return; } if (input.isFinished()) { complete = true; asyncContext.complete(); } } @Override public void onAllDataRead() throws IOException {} @Override public void onWritePossible() throws IOException { if (input.isFinished()) { if (!complete) asyncContext.complete(); } else { onDataAvailable(); } } @Override public void onError(Throwable failure) { failure.printStackTrace(); } } }
  • 34. Maybe something simpler 34 protected void doGet(HttpServletRequest req, HttpServletResponse resp) { AsyncContext asyncContext = request.startAsync(request, response); final ServletOutputStream out = resp.getOutputStream(); final byte[] buf = new byte[1024]; final FileInputStream file = …; out.setWriteListener(new WriteListener() { @Override public void onWritePossible() throws IOException { while(out.isReady()) { int len = file.read(buf); if(len<0) { return; } out.write(buf, 0, len); } } }); }
  • 37. Node.js 37 var server = http.createServer(function (req, res) { req.pipe(res); });
  • 38. Node.js 38 var server = http.createServer(function (req, res) { req.pipe(res); });
  • 42. Observable<T> 42 Will push zero or more items of type T Followed by a ‘completed’ message (or an error…)
  • 43. RxJava Quick Intro 43 Observable.<String>just("Ouagadougou","Dakar","Accra","Rabat") .subscribe(item->System.err.println(item)); Ouagadougou Dakar Accra Rabat
  • 44. RxJava Quick Intro 44 Observable.range(0, 1000) .subscribe(item->System.err.println(item)); 0 1 2 3 4 5 6 … 998 999
  • 45. RxJava Quick Intro 45 Observable.range(0, 1000) .skip(10) .take(10) .subscribe(item->System.err.println(item)); 10 11 12 13 14 15 16 17 18 19
  • 46. RxJava Quick Intro 46 Bytes.fromFile("citiesafrica.xml") .lift(XML.parse()) .subscribe(item->System.err.println(item)); <cities> <africa> <city name="Lusaka"/> <city name="Harare"/> <city name="Kigali"/> </africa> </cities> START_DOCUMENT START_ELEMENT cities {} START_ELEMENT africa {} START_ELEMENT city {name=Lusaka} END_ELEMENT city START_ELEMENT city {name=Harare} END_ELEMENT city START_ELEMENT city {name=Kigali} END_ELEMENT city END_ELEMENT africa END_ELEMENT cities END_DOCUMENT
  • 47. RxJava Quick Intro 47 Bytes.fromFile("citiesafrica.xml") .lift(XML.parse()) .filter(e->e.getType()==XmlEventTypes.START_ELEMENT) .map(e->e.getAttributes().get("name")) .subscribe(item->System.err.println(item)); <cities> <africa> <city name="Lusaka"/> <city name="Harare"/> <city name="Kigali"/> </africa> </cities> Lusaka Harare Kigali
  • 48. static Observable<byte[]> createSourceObservable(HttpServletRequest req); static Subscriber<byte[]> createSink(HttpServletResponse resp); protected void doPost(HttpServletRequest req, final HttpServletResponse resp) { createSourceObservable(req) .subscribe(createSink(resp)); } RxJava Quick Intro
  • 50. A Blocking API public static Double temperatureInCity(String city) { return Double.parseDouble(HTTPClient .get("http://api.weather.org/weather?q="+city) .toXml() .getContent("temperature")); } For consumers: Double temperature = temperatureInCity("Tripoli");
  • 51. Convert to Reactive public Observable<Double> temperatureInCity(String city) { return Observable.just( Double.parseDouble(HTTPClient .get("http://api.weather.org/weather?q="+city) .toXml() .getContent("temperature") )); }
  • 53. Sort of… Double temp = temperatureInCity(“Cairo”).blockingFirst(); updateTemperatureUI(temp); This code is still just as blocking But now the consumer and producer have independent threading
  • 54. Use a Non Blocking HTTP Client public static Observable<Double> temperatureInCity(String city) { return HTTP.get("http://api.weather.org/weather?q="+city) .subscribeOn(Schedulers.io()) .lift(XML.parse()) .filter(e->e.getType()==XmlEventTypes.START_ELEMENT) .filter(e->e.getText().equals("temperature")) .first() .map(xml->Double.parseDouble(xml.getAttributes().get("value"))); }
  • 55. Add a Cache public Observable<Double> temperatureInCity(String city) { Double temperature = temperatureCache.get(city); if(temperature!=null) { return Observable.just(temperature); } return HTTP.get("http://api.weather.org/weather?q="+city) .subscribeOn(Schedulers.io()) .lift(XML.parse()) .filter(e->e.getType()==XmlEventTypes.START_ELEMENT) .filter(e->e.getText().equals("temperature")) .first() .map(xml->Double.parseDouble(xml.getAttributes().get("value"))) .doOnNext(temperature->temperatureCache.put(city,temperature)); }
  • 56. Non Blocking Client Blocking: Double temp = temperatureInCity(“Cairo").toBlocking().first(); updateTemperatureUI(temp); Non blocking: temperatureInCity(“Nairobi”) .observeOn(UISchedulers.uiThread()) .subscribe(d->updateTemperatureUI(d));
  • 60. A Blocking Echo Servlet 60 public class BlockingServlet extends HttpServlet { private static final int BUFFER_SIZE = 1024; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { byte[] buffer = new byte[BUFFER_SIZE]; while (true) { int read = request.getInputStream().read(buffer, 0, BUFFER_SIZE); if (read < 0) break; response.getOutputStream().write(buffer, 0, read); } } }
  • 61. Back pressure 61 ! Observable: No back pressure ! Flowable: Back pressure
  • 62. RxJava back pressure 62 Bytes.fromNetwork(“something_huge.xml”) .lift(XML.parse()) .filter(e->e.getType()==XmlEventTypes.START_ELEMENT) .map(e->e.getAttributes().get("name")) .subscribe(item->doSomethingComplicated(item));
  • 65. Memory Consumption 65 ! Much better ! … or much worse
  • 66. Error Handling 66 ! Some patterns don’t work any more ! Requires some thought
  • 67. Error handling 67 Servlet.handlePost() .lift(XML.parse()) .subscribe(item->sendSomeWhere(item)); <cities> <africa> <city name="Lusaka"/> <city name="Harare"/> <city name="Kigali"/> </cities> START_DOCUMENT START_ELEMENT cities {} START_ELEMENT africa {} START_ELEMENT city {name=Lusaka} END_ELEMENT city START_ELEMENT city {name=Harare} END_ELEMENT city START_ELEMENT city {name=Kigali} END_ELEMENT city END_ELEMENT africa PARSE_ERROR
  • 68. Non Blocking is not faster 68 ! It is about utilising threads better ! If thread utilisation is not an issue, it will perform similarly
  • 69. Thoughts 69 ! RxJava is lightweight and easy to add to existing software ! Pleasant programming model ! Makes non blocking I/O bearable ! Can be used incrementally
  • 70. Conclusions 70 ! Threads are expensive ! Everything keeps getting faster except the speed of light ! Micro services ! Blocking code misbehaves under pressure ! The price of blocking communication will keep going up I believe that, in time, some non blocking code is inevitable