SlideShare a Scribd company logo
1 of 58
Simone Bordet
sbordet@webtide.com
Scale your Web Applications
with
Servlet 3.1 Async I/O
Simone Bordet
sbordet@webtide.com
Who Am I
 Simone Bordet
 sbordet@intalio.com
 @simonebordet
 Open Source Contributor
 Jetty, CometD, MX4J, Foxtrot, LiveTribe, JBoss, Larex
 Lead Architect at Intalio/Webtide
 Jetty's HTTP/2, SPDY and HTTP client maintainer
 CometD project leader
 Web messaging framework
 JVM tuning expert
Simone Bordet
sbordet@webtide.com
Agenda
 Why Async ?
 Async Everywhere
 Async I/O API in the Servlet 3.1 Specification
 Correctly use the new Servlet Async I/O APIs
Simone Bordet
sbordet@webtide.com
Why Async ?
Simone Bordet
sbordet@webtide.com
Why Async ?
Client Server RDBMS
Simone Bordet
sbordet@webtide.com
Why Async ?
Client Server RDBMS
Blocking
Wait
Simone Bordet
sbordet@webtide.com
Why Async ?
 Why blocking waits are bad ?
 They consume resources
 Native Thread
 Native Memory (thread stack: 1 MiB per thread)
 OS scheduler data structures
 ThreadLocals
 Local variables in the stack frames
 GC has to walk the stack frames
 Blocking waits == $$$
Simone Bordet
sbordet@webtide.com
Why Async ?
Client Server REST
Async
Wait
Simone Bordet
sbordet@webtide.com
REST
Why Async ?
Client Server NOSQL
Multiple
operations
Simone Bordet
sbordet@webtide.com
Why Async ?
Client Server REST
Client
Client
Multiple
clients
Simone Bordet
sbordet@webtide.com
Why Async ?
 Improved latency
 By performing tasks concurrently with less resources
 Better resource utilization
 The SAME thread can serve multiple clients
 Async waits == $
 Async == Increased performance
 Increased performance == $$$
Simone Bordet
sbordet@webtide.com
Why Async ?
Simone Bordet
sbordet@webtide.com
Demo
https://webtide.com/async-rest/
Simone Bordet
sbordet@webtide.com
Async Everywhere
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Until few years ago parallelism was not widespread
 Single core CPUs
 Modern hardware has gone multi-core
 We want to be able to use those cores
 Future hardware will have even more cores
 We need to leverage hw parallelism in software
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Async programming is not new
 Spawning a thread is a primitive in OS since day one
 Async programming is difficult...
 … to write: callback hell, synchronization
 … to read: our brain reads from top to bottom
 New APIs are born
 epoll, promises, actors, channels, etc.
 New products are born
 Nginx vs Apache, etc.
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Example: Java 8 CompletableFuture
CompletableFuture
.supplyAsync(() -> fetchQueryFromREST(uri))
.thenApplyAsync(sql -> fetchDataFromNOSQL(sql))
.thenAccept(data -> updateUI(data));
 We want a way to read code as if it is sequential
 But in fact it is asynchronous
 You have to marry the API model
 Always use the model, no exceptions
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Servlet 3.0: async processing of response
void doGet(request, response)
{
OutputStream out = response.getOutputStream();
AsyncContext ctx = request.startAsync();
doAsyncREST(request).thenAccept(json -> {
out.write(json);
ctx.complete();
});
}
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Two requirements for an async Servlet
 First requirement: doAsyncREST()
 Must use async libraries to do its work
 Must return a CompletableFuture
 Or take a callback parameter (or something similar)
 Second requirement: thenAccept() lambda
 Must use async libraries
Simone Bordet
sbordet@webtide.com
Async Everywhere
 ✗ JDBC
 ✗ InputStream – OutputStream
 ✔ Asynchronous I/O (NIO2: files, sockets)
 ✔ REST
 ✔ Call other Servlets
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Servlet 3.0: no async I/O
void doGet(request, response)
{
OutputStream out = response.getOutputStream();
AsyncContext ctx = request.startAsync();
doAsyncREST(request).thenAccept(json -> {
out.write(json); Blocking!
ctx.complete();
});
}
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Finally! That's why Servlet 3.1 introduced async I/O
 What API to use then ?
 Use java.util.concurrent.Future ?
Future<Integer> f = out.write(json);
int written = f.get().intValue();
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Finally! That's why Servlet 3.1 introduced async I/O !
 What API to use then ?
 Use java.util.concurrent.Future ?
Future<Integer> f = channel.write(json);
int written = f.get().intValue();
This is just delayed
blocking, not async
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Use NIO2 ?
out.write(json, null, new CompletionHandler()
{
void completed(Integer written, Object obj)
{
ctx.complete();
}
void failed(Throwable x, Object obj) {
}
}
Simone Bordet
sbordet@webtide.com
Async Everywhere
 Use NIO2 ?
out.write(json, null, new CompletionHandler()
{
void completed(Integer written, Object obj)
{
ctx.complete();
}
void failed(Throwable x, Object obj) {
}
}
Allocation Not a lambda
Not thread efficient
Prone to stack overflow
(resolved by further
thread dispatching)
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Servlet 3.1 async write I/O APIs
void doGet(request, response) {
ServletOutputStream out = response.getOutputStream();
AsyncContext ctx = request.startAsync();
out.setWriteListener(new WriteListener() {
void onWritePossible() {
while (out.isReady()) {
byte[] buffer = readFromSomeWhere();
if (buffer != null)
out.write(buffer);
else
ctx.complete();
}}});}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Servlet 3.1 async write I/O APIs
void doGet(request, response) {
ServletOutputStream out = response.getOutputStream();
AsyncContext ctx = request.startAsync();
out.setWriteListener(new WriteListener() {
void onWritePossible() {
while (out.isReady()) {
byte[] buffer = readFromSomeWhere();
if (buffer != null)
out.write(buffer);
else
ctx.complete(); break;
}}});}
Iterative
Async write
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Normal writes (fast connection)
 Iterative writes in the same thread
 No thread dispatch
 No stack overflow
 No allocation
 Incomplete writes (slow connection)
 Some iterative write, then isReady() returns false
 When ready again, new thread calls onWritePossible()
 Got it ! Is it really this simple ?
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #1
void onWritePossible()
{
out.write(allContent);
logger.debug("written: {}", out.isReady());
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #1
void onWritePossible()
{
out.write(allContent);
logger.debug("written: {}", out.isReady());
}
 Content is written twice !
When isReady() == false
onWritePossible() will
be called again !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #2
void onWritePossible()
{
if (dataAvailable() && out.isReady())
out.write(getData());
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #2
void onWritePossible()
{
if (dataAvailable() && out.isReady())
out.write(getData());
}
 If dataAvailable() returns false, isReady() is not
called and onWritePossible() will never be called
 Switching the if expressions changes the semantic
The order of the
expressions in the if
statement is
significant !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #3
void onWritePossible()
{
if (out.isReady()) {
out.write(“<h1>Async</h1>”);
out.write(“<p>Content</p>”);
}
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #3
void onWritePossible()
{
if (out.isReady()) {
out.write(“<h1>Async</h1>”);
out.write(“<p>Content</p>”);
}
}
 You HAVE to use isReady() after each write
The first write
may be pending !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #4
void onWritePossible()
{
if (out.isReady()) {
out.write(“<h1>Async</h1>”);
if (out.isReady())
out.write(“<p>Content</p>”);
}
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #4
void onWritePossible()
{
if (out.isReady()) {
out.write(“<h1>Async</h1>”);
if (out.isReady())
out.write(“<p>Content</p>”);
}
}
 Don't misuse isReady()
Content written
multiple times !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #5
void onWritePossible()
{
int read = file.read(buffer);
while (out.isReady()) {
out.write(buffer);
if (file.read(buffer) < 0)
ctx.complete(); return;
}
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #5
void onWritePossible()
{
int read = file.read(buffer);
while (out.isReady()) {
out.write(buffer);
if (file.read(buffer) < 0)
ctx.complete(); return;
}
}
 The buffer is overwritten by the new read
Write may be
pending: you
don't own
the buffer
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #6
void onWritePossible()
{
try {
...
} catch (Exception x) {
response.sendError(500);
}
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #6
void onWritePossible()
{
try {
...
} catch (Exception x) {
response.sendError(500);
}
}
 Cannot mix async I/O and blocking I/O
sendError() is a
blocking API !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 When ServletOutputStream is put into async mode:
 Quacks like a stream
 Walks like a stream
 But it's NOT a stream !
 Broken semantic:
 OutputStream.write() is expected to be blocking !
 ServletOutputStream.isReady(): a query with side effects !
 Breaking semantic consequences:
 Filters and wrappers are broken !
 Cannot tell whether the stream is async or not
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Servlet 3.1 async read I/O APIs
void doPost(request, response)
{
AsyncContext ctx = request.startAsync();
ServletInputStream in = request.getInputStream();
in.setReadListener(new ReadListener() {
void onDataAvailable() {
while (in.isReady() && !in.isFinished()) {
int len = in.read(buffer);
if (len > 0)
store(buffer); // Blocking API
if (in.isFinished())
ctx.complete(); return;
}}});}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Servlet 3.1 async read I/O APIs
void doPost(request, response)
{
AsyncContext ctx = request.startAsync();
ServletInputStream in = request.getInputStream();
in.setReadListener(new ReadListener() {
void onDataAvailable() {
while (in.isReady() && !in.isFinished()) {
int len = input.read(buffer);
if (len > 0)
store(buffer); // Blocking API
if (in.isFinished())
ctx.complete(); return;
}}});}
Iterative
Async read
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Normal reads (fast connection)
 Iterative reads in the same thread
 No thread dispatch
 No stack overflow
 No allocation
 Incomplete reads (slow connection)
 Some iterative reads, then isReady() returns false
 When ready again, new thread calls onDataAvailable()
 Got it ! Is it really this simple ?
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #1
void onDataAvailable() {
while (in.isReady()) {
in.read(buffer);
store(buffer);
}
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #1
void onDataAvailable() {
while (in.isReady()) {
in.read(buffer);
store(buffer);
}
}
 Infinite loop
 The loop must call also in.isFinished()
isReady() returns
true at EOF
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #2
void onDataAvailable() {
while (in.isReady() && !in.isFinished()) {
int read = in.read(buffer);
store(buffer, new Callback() {
void done() {
onDataAvailable();
}
});
}
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #2
void onDataAvailable() {
while (in.isReady() && !in.isFinished()) {
int read = in.read(buffer);
store(buffer, new Callback() {
void done() {
onDataAvailable();
}
});
}
}
 Stack overflows for fast connections
 Mixing different async models requires more careful coding
 Jetty's IteratingCallback is one solution
Stack overflow !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #3
void onDataAvailable() {
String id = request.getParameter(“id”);
...
}
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Bug #3
void onDataAvailable() {
String id = request.getParameter(“id”);
...
}
 Same with request.getParts()
 Multipart APIs
Blocking API !
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
public class SyncServlet extends HttpServlet
{
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);
}
}
}
public static class AsyncServlet extends HttpServlet
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExcepti
{
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();
}
}
}
Echo Servlet Async I/OEcho Servlet Blocking I/O
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Async I/O Echo Servlet
 Pros
 Async
 Cons
 4x-6x more code
 Requires a state machine (a simple boolean, but still)
 More difficult buffer handling
 Complexity, maintainability, etc.
Simone Bordet
sbordet@webtide.com
Conclusions
Simone Bordet
sbordet@webtide.com
Servlet 3.1 Async I/O
 Blocking code has a reason to exist
 And will continue to exist
 Is the async I/O complexity worth it ?
 For a class of applications, YES !
 Improved scalability
 Decreased latency
 Makes you more money
Simone Bordet
sbordet@webtide.com
Takeaway #1
https://webtide.com/async-rest/
Simone Bordet
sbordet@webtide.com
Takeaway #2
Simone Bordet
sbordet@webtide.com
Questions
&
Answers

More Related Content

What's hot

What's hot (20)

Puppeteer can automate that! - Frontmania
Puppeteer can automate that! - FrontmaniaPuppeteer can automate that! - Frontmania
Puppeteer can automate that! - Frontmania
 
WebAssembly Overview
WebAssembly OverviewWebAssembly Overview
WebAssembly Overview
 
Async/Await
Async/AwaitAsync/Await
Async/Await
 
Java nio ( new io )
Java nio ( new io )Java nio ( new io )
Java nio ( new io )
 
Injecting Security into Web apps at Runtime Whitepaper
Injecting Security into Web apps at Runtime WhitepaperInjecting Security into Web apps at Runtime Whitepaper
Injecting Security into Web apps at Runtime Whitepaper
 
Puppeteer
PuppeteerPuppeteer
Puppeteer
 
An Introduction to WebAssembly
An Introduction to WebAssemblyAn Introduction to WebAssembly
An Introduction to WebAssembly
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
 
Introduction to webassembly
Introduction to webassemblyIntroduction to webassembly
Introduction to webassembly
 
WebAssembly: In a Nutshell
WebAssembly: In a NutshellWebAssembly: In a Nutshell
WebAssembly: In a Nutshell
 
Adventures with Podman and Varlink
Adventures with Podman and VarlinkAdventures with Podman and Varlink
Adventures with Podman and Varlink
 
WebAssembly Fundamentals
WebAssembly FundamentalsWebAssembly Fundamentals
WebAssembly Fundamentals
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
 
Puppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node APIPuppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node API
 
Javaday Paris 2022 - Java en 2022 : profiter de Java 17
Javaday Paris 2022 - Java en 2022 : profiter de Java 17Javaday Paris 2022 - Java en 2022 : profiter de Java 17
Javaday Paris 2022 - Java en 2022 : profiter de Java 17
 
Do we need Unsafe in Java?
Do we need Unsafe in Java?Do we need Unsafe in Java?
Do we need Unsafe in Java?
 
Java NIO.2
Java NIO.2Java NIO.2
Java NIO.2
 

Viewers also liked

Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]
Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]
Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]
Bert Ertman
 
Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013
Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013
Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013
Eric Seufert
 
Using Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek SafarUsing Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek Safar
Xamarin
 

Viewers also liked (20)

HTTP/2 and Java: Current Status
HTTP/2 and Java: Current StatusHTTP/2 and Java: Current Status
HTTP/2 and Java: Current Status
 
Servlet 3.1
Servlet 3.1Servlet 3.1
Servlet 3.1
 
HTTP/2 Comes to Java
HTTP/2 Comes to JavaHTTP/2 Comes to Java
HTTP/2 Comes to Java
 
G1 Garbage Collector: Details and Tuning
G1 Garbage Collector: Details and TuningG1 Garbage Collector: Details and Tuning
G1 Garbage Collector: Details and Tuning
 
JavaOne San Francisco 2013 - Servlet 3.1 (JSR 340)
JavaOne San Francisco 2013 - Servlet 3.1 (JSR 340)JavaOne San Francisco 2013 - Servlet 3.1 (JSR 340)
JavaOne San Francisco 2013 - Servlet 3.1 (JSR 340)
 
Cloud-Ready Web Messaging with CometD
Cloud-Ready Web Messaging with CometDCloud-Ready Web Messaging with CometD
Cloud-Ready Web Messaging with CometD
 
Building Modular Cloud Applications in Java - Lessons Learned
Building Modular Cloud Applications in Java - Lessons LearnedBuilding Modular Cloud Applications in Java - Lessons Learned
Building Modular Cloud Applications in Java - Lessons Learned
 
VJUG - Building Modular Java Applications in the Cloud Age
VJUG - Building Modular Java Applications in the Cloud AgeVJUG - Building Modular Java Applications in the Cloud Age
VJUG - Building Modular Java Applications in the Cloud Age
 
Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]
Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]
Migrating from Spring Applications to Java EE 6 [CHINESE VERSION]
 
The Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allThe Eff monad, one monad to rule them all
The Eff monad, one monad to rule them all
 
Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013
Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013
Big Data in Mobile Gaming - Eric Seufert presentation from IGExpo Feb 1 2013
 
Async and Await on the Server
Async and Await on the ServerAsync and Await on the Server
Async and Await on the Server
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java
 
From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!
 
Sync with async
Sync with  asyncSync with  async
Sync with async
 
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
 
How to meets Async and Task
How to meets Async and TaskHow to meets Async and Task
How to meets Async and Task
 
Microservices for Mortals
Microservices for MortalsMicroservices for Mortals
Microservices for Mortals
 
Promises And Chaining In AngularJS - Into Callback Hell And Back Again
Promises And Chaining In AngularJS - Into Callback Hell And Back AgainPromises And Chaining In AngularJS - Into Callback Hell And Back Again
Promises And Chaining In AngularJS - Into Callback Hell And Back Again
 
Using Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek SafarUsing Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek Safar
 

Similar to Servlet 3.1 Async I/O

The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
jeffz
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Tatsuhiko Miyagawa
 
Real-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.ioReal-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.io
Rick Copeland
 

Similar to Servlet 3.1 Async I/O (20)

Tech Webinar: AUMENTARE LA SCALABILITÀ DELLE WEB APP CON SERVLET 3.1 ASYNC I/O
Tech Webinar: AUMENTARE LA SCALABILITÀ DELLE WEB APP CON SERVLET 3.1 ASYNC I/OTech Webinar: AUMENTARE LA SCALABILITÀ DELLE WEB APP CON SERVLET 3.1 ASYNC I/O
Tech Webinar: AUMENTARE LA SCALABILITÀ DELLE WEB APP CON SERVLET 3.1 ASYNC I/O
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
 
The current state of web
The current state of webThe current state of web
The current state of web
 
aiohttp intro
aiohttp introaiohttp intro
aiohttp intro
 
Tamir Dresher - What’s new in ASP.NET Core 6
Tamir Dresher - What’s new in ASP.NET Core 6Tamir Dresher - What’s new in ASP.NET Core 6
Tamir Dresher - What’s new in ASP.NET Core 6
 
HOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOP
HOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOPHOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOP
HOW TO DEAL WITH BLOCKING CODE WITHIN ASYNCIO EVENT LOOP
 
Time for intersection observer
Time for intersection observerTime for intersection observer
Time for intersection observer
 
BUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOBUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIO
 
History of asynchronous in .NET
History of asynchronous in .NETHistory of asynchronous in .NET
History of asynchronous in .NET
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
Async Programming in C# 5
Async Programming in C# 5Async Programming in C# 5
Async Programming in C# 5
 
Server Side JavaScript: Ajax.org O3
Server Side JavaScript: Ajax.org O3Server Side JavaScript: Ajax.org O3
Server Side JavaScript: Ajax.org O3
 
Server Side JavaScript: Ajax.org O3.
Server Side JavaScript: Ajax.org O3.Server Side JavaScript: Ajax.org O3.
Server Side JavaScript: Ajax.org O3.
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
 
Real-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.ioReal-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.io
 
Java Hurdling: Obstacles and Techniques in Java Client Penetration-Testing
Java Hurdling: Obstacles and Techniques in Java Client Penetration-TestingJava Hurdling: Obstacles and Techniques in Java Client Penetration-Testing
Java Hurdling: Obstacles and Techniques in Java Client Penetration-Testing
 
Why async matters
Why async mattersWhy async matters
Why async matters
 
692015 programming assignment 1 building a multi­threaded w
692015 programming assignment 1 building a multi­threaded w692015 programming assignment 1 building a multi­threaded w
692015 programming assignment 1 building a multi­threaded w
 
Python, do you even async?
Python, do you even async?Python, do you even async?
Python, do you even async?
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Recently uploaded (20)

A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 

Servlet 3.1 Async I/O

  • 1. Simone Bordet sbordet@webtide.com Scale your Web Applications with Servlet 3.1 Async I/O
  • 2. Simone Bordet sbordet@webtide.com Who Am I  Simone Bordet  sbordet@intalio.com  @simonebordet  Open Source Contributor  Jetty, CometD, MX4J, Foxtrot, LiveTribe, JBoss, Larex  Lead Architect at Intalio/Webtide  Jetty's HTTP/2, SPDY and HTTP client maintainer  CometD project leader  Web messaging framework  JVM tuning expert
  • 3. Simone Bordet sbordet@webtide.com Agenda  Why Async ?  Async Everywhere  Async I/O API in the Servlet 3.1 Specification  Correctly use the new Servlet Async I/O APIs
  • 6. Simone Bordet sbordet@webtide.com Why Async ? Client Server RDBMS Blocking Wait
  • 7. Simone Bordet sbordet@webtide.com Why Async ?  Why blocking waits are bad ?  They consume resources  Native Thread  Native Memory (thread stack: 1 MiB per thread)  OS scheduler data structures  ThreadLocals  Local variables in the stack frames  GC has to walk the stack frames  Blocking waits == $$$
  • 8. Simone Bordet sbordet@webtide.com Why Async ? Client Server REST Async Wait
  • 9. Simone Bordet sbordet@webtide.com REST Why Async ? Client Server NOSQL Multiple operations
  • 10. Simone Bordet sbordet@webtide.com Why Async ? Client Server REST Client Client Multiple clients
  • 11. Simone Bordet sbordet@webtide.com Why Async ?  Improved latency  By performing tasks concurrently with less resources  Better resource utilization  The SAME thread can serve multiple clients  Async waits == $  Async == Increased performance  Increased performance == $$$
  • 15. Simone Bordet sbordet@webtide.com Async Everywhere  Until few years ago parallelism was not widespread  Single core CPUs  Modern hardware has gone multi-core  We want to be able to use those cores  Future hardware will have even more cores  We need to leverage hw parallelism in software
  • 16. Simone Bordet sbordet@webtide.com Async Everywhere  Async programming is not new  Spawning a thread is a primitive in OS since day one  Async programming is difficult...  … to write: callback hell, synchronization  … to read: our brain reads from top to bottom  New APIs are born  epoll, promises, actors, channels, etc.  New products are born  Nginx vs Apache, etc.
  • 17. Simone Bordet sbordet@webtide.com Async Everywhere  Example: Java 8 CompletableFuture CompletableFuture .supplyAsync(() -> fetchQueryFromREST(uri)) .thenApplyAsync(sql -> fetchDataFromNOSQL(sql)) .thenAccept(data -> updateUI(data));  We want a way to read code as if it is sequential  But in fact it is asynchronous  You have to marry the API model  Always use the model, no exceptions
  • 18. Simone Bordet sbordet@webtide.com Async Everywhere  Servlet 3.0: async processing of response void doGet(request, response) { OutputStream out = response.getOutputStream(); AsyncContext ctx = request.startAsync(); doAsyncREST(request).thenAccept(json -> { out.write(json); ctx.complete(); }); }
  • 19. Simone Bordet sbordet@webtide.com Async Everywhere  Two requirements for an async Servlet  First requirement: doAsyncREST()  Must use async libraries to do its work  Must return a CompletableFuture  Or take a callback parameter (or something similar)  Second requirement: thenAccept() lambda  Must use async libraries
  • 20. Simone Bordet sbordet@webtide.com Async Everywhere  ✗ JDBC  ✗ InputStream – OutputStream  ✔ Asynchronous I/O (NIO2: files, sockets)  ✔ REST  ✔ Call other Servlets
  • 21. Simone Bordet sbordet@webtide.com Async Everywhere  Servlet 3.0: no async I/O void doGet(request, response) { OutputStream out = response.getOutputStream(); AsyncContext ctx = request.startAsync(); doAsyncREST(request).thenAccept(json -> { out.write(json); Blocking! ctx.complete(); }); }
  • 22. Simone Bordet sbordet@webtide.com Async Everywhere  Finally! That's why Servlet 3.1 introduced async I/O  What API to use then ?  Use java.util.concurrent.Future ? Future<Integer> f = out.write(json); int written = f.get().intValue();
  • 23. Simone Bordet sbordet@webtide.com Async Everywhere  Finally! That's why Servlet 3.1 introduced async I/O !  What API to use then ?  Use java.util.concurrent.Future ? Future<Integer> f = channel.write(json); int written = f.get().intValue(); This is just delayed blocking, not async
  • 24. Simone Bordet sbordet@webtide.com Async Everywhere  Use NIO2 ? out.write(json, null, new CompletionHandler() { void completed(Integer written, Object obj) { ctx.complete(); } void failed(Throwable x, Object obj) { } }
  • 25. Simone Bordet sbordet@webtide.com Async Everywhere  Use NIO2 ? out.write(json, null, new CompletionHandler() { void completed(Integer written, Object obj) { ctx.complete(); } void failed(Throwable x, Object obj) { } } Allocation Not a lambda Not thread efficient Prone to stack overflow (resolved by further thread dispatching)
  • 27. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Servlet 3.1 async write I/O APIs void doGet(request, response) { ServletOutputStream out = response.getOutputStream(); AsyncContext ctx = request.startAsync(); out.setWriteListener(new WriteListener() { void onWritePossible() { while (out.isReady()) { byte[] buffer = readFromSomeWhere(); if (buffer != null) out.write(buffer); else ctx.complete(); }}});}
  • 28. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Servlet 3.1 async write I/O APIs void doGet(request, response) { ServletOutputStream out = response.getOutputStream(); AsyncContext ctx = request.startAsync(); out.setWriteListener(new WriteListener() { void onWritePossible() { while (out.isReady()) { byte[] buffer = readFromSomeWhere(); if (buffer != null) out.write(buffer); else ctx.complete(); break; }}});} Iterative Async write
  • 29. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Normal writes (fast connection)  Iterative writes in the same thread  No thread dispatch  No stack overflow  No allocation  Incomplete writes (slow connection)  Some iterative write, then isReady() returns false  When ready again, new thread calls onWritePossible()  Got it ! Is it really this simple ?
  • 30. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #1 void onWritePossible() { out.write(allContent); logger.debug("written: {}", out.isReady()); }
  • 31. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #1 void onWritePossible() { out.write(allContent); logger.debug("written: {}", out.isReady()); }  Content is written twice ! When isReady() == false onWritePossible() will be called again !
  • 32. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #2 void onWritePossible() { if (dataAvailable() && out.isReady()) out.write(getData()); }
  • 33. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #2 void onWritePossible() { if (dataAvailable() && out.isReady()) out.write(getData()); }  If dataAvailable() returns false, isReady() is not called and onWritePossible() will never be called  Switching the if expressions changes the semantic The order of the expressions in the if statement is significant !
  • 34. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #3 void onWritePossible() { if (out.isReady()) { out.write(“<h1>Async</h1>”); out.write(“<p>Content</p>”); } }
  • 35. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #3 void onWritePossible() { if (out.isReady()) { out.write(“<h1>Async</h1>”); out.write(“<p>Content</p>”); } }  You HAVE to use isReady() after each write The first write may be pending !
  • 36. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #4 void onWritePossible() { if (out.isReady()) { out.write(“<h1>Async</h1>”); if (out.isReady()) out.write(“<p>Content</p>”); } }
  • 37. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #4 void onWritePossible() { if (out.isReady()) { out.write(“<h1>Async</h1>”); if (out.isReady()) out.write(“<p>Content</p>”); } }  Don't misuse isReady() Content written multiple times !
  • 38. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #5 void onWritePossible() { int read = file.read(buffer); while (out.isReady()) { out.write(buffer); if (file.read(buffer) < 0) ctx.complete(); return; } }
  • 39. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #5 void onWritePossible() { int read = file.read(buffer); while (out.isReady()) { out.write(buffer); if (file.read(buffer) < 0) ctx.complete(); return; } }  The buffer is overwritten by the new read Write may be pending: you don't own the buffer
  • 40. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #6 void onWritePossible() { try { ... } catch (Exception x) { response.sendError(500); } }
  • 41. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #6 void onWritePossible() { try { ... } catch (Exception x) { response.sendError(500); } }  Cannot mix async I/O and blocking I/O sendError() is a blocking API !
  • 42. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  When ServletOutputStream is put into async mode:  Quacks like a stream  Walks like a stream  But it's NOT a stream !  Broken semantic:  OutputStream.write() is expected to be blocking !  ServletOutputStream.isReady(): a query with side effects !  Breaking semantic consequences:  Filters and wrappers are broken !  Cannot tell whether the stream is async or not
  • 43. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Servlet 3.1 async read I/O APIs void doPost(request, response) { AsyncContext ctx = request.startAsync(); ServletInputStream in = request.getInputStream(); in.setReadListener(new ReadListener() { void onDataAvailable() { while (in.isReady() && !in.isFinished()) { int len = in.read(buffer); if (len > 0) store(buffer); // Blocking API if (in.isFinished()) ctx.complete(); return; }}});}
  • 44. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Servlet 3.1 async read I/O APIs void doPost(request, response) { AsyncContext ctx = request.startAsync(); ServletInputStream in = request.getInputStream(); in.setReadListener(new ReadListener() { void onDataAvailable() { while (in.isReady() && !in.isFinished()) { int len = input.read(buffer); if (len > 0) store(buffer); // Blocking API if (in.isFinished()) ctx.complete(); return; }}});} Iterative Async read
  • 45. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Normal reads (fast connection)  Iterative reads in the same thread  No thread dispatch  No stack overflow  No allocation  Incomplete reads (slow connection)  Some iterative reads, then isReady() returns false  When ready again, new thread calls onDataAvailable()  Got it ! Is it really this simple ?
  • 46. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #1 void onDataAvailable() { while (in.isReady()) { in.read(buffer); store(buffer); } }
  • 47. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #1 void onDataAvailable() { while (in.isReady()) { in.read(buffer); store(buffer); } }  Infinite loop  The loop must call also in.isFinished() isReady() returns true at EOF
  • 48. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #2 void onDataAvailable() { while (in.isReady() && !in.isFinished()) { int read = in.read(buffer); store(buffer, new Callback() { void done() { onDataAvailable(); } }); } }
  • 49. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #2 void onDataAvailable() { while (in.isReady() && !in.isFinished()) { int read = in.read(buffer); store(buffer, new Callback() { void done() { onDataAvailable(); } }); } }  Stack overflows for fast connections  Mixing different async models requires more careful coding  Jetty's IteratingCallback is one solution Stack overflow !
  • 50. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #3 void onDataAvailable() { String id = request.getParameter(“id”); ... }
  • 51. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Bug #3 void onDataAvailable() { String id = request.getParameter(“id”); ... }  Same with request.getParts()  Multipart APIs Blocking API !
  • 52. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O public class SyncServlet extends HttpServlet { 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); } } } public static class AsyncServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExcepti { 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(); } } } Echo Servlet Async I/OEcho Servlet Blocking I/O
  • 53. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Async I/O Echo Servlet  Pros  Async  Cons  4x-6x more code  Requires a state machine (a simple boolean, but still)  More difficult buffer handling  Complexity, maintainability, etc.
  • 55. Simone Bordet sbordet@webtide.com Servlet 3.1 Async I/O  Blocking code has a reason to exist  And will continue to exist  Is the async I/O complexity worth it ?  For a class of applications, YES !  Improved scalability  Decreased latency  Makes you more money