Upload
domingo-suarez-torres
View
821
Download
3
Embed Size (px)
Citation preview
Ratpack@jvm_mx Meetup / CDMX / February 2016
Ratpack
Ratpack
• Originally written in Groovy
• Now a Java 8 code base project.
• It uses Apache Netty
• Apache 2.0 Licensed
• Fully Groovy support!
demo.groovy@Grab('org.slf4j:slf4j-simple:1.7.16') @Grab('io.ratpack:ratpack-groovy:1.2.0') import static ratpack.groovy.Groovy.ratpack
ratpack { handlers { get(":name") { render "Hello $pathTokens.name!" } get { render "Hello World!" } } }
Java project demoplugins { id 'io.ratpack.ratpack-java' version '1.2.0' }
apply plugin: 'idea'
repositories { jcenter() }
dependencies { runtime 'org.slf4j:slf4j-simple:1.7.16' testCompile 'junit:junit:4.12' }
mainClassName = 'org.groovyando.Main'
Ratpack 101
• Ratpack uses Apache Netty, an async event-driven network application framework.
• Ratpack is not Servlet API-based, so don’t expect things HttpServletRequest or HttpSession.
Ratpack key features
• Strongly typed
• Non blocking
What is blocking?
Blocking
• Any IO operation
• InputStream
• Lock.lock()
• JDBC
• 99% of all APIs out there!!
Contention = threads > cores
Blocking and threadsEach concurrent piece of
work requires a separate thread.
100 concurrent requests =~ 100 threads
C10K Problem?
https://en.wikipedia.org/wiki/C10k_problem
The C10k problem is the problem of optimising network sockets to handle a large number of clients at the same time. The name C10k is a numeronym for concurrently handling ten thousand connections. Note that concurrent connections are not the same as requests per second, though they are similar: handling many requests per second requires high throughput (processing them quickly), while high number of concurrent connections requires efficient scheduling of connections.
Ratpack components
• Launch Configuration
• Handlers
• Registry
Handlers
• Handlers as a mix of a Servlet and a Filter.
• Each handler receives a Context object to interact with the request & response objects, the chain, etc.
Handlers
• Handlers are functions composed in a handler chain. A handler can do one of the following:
• Respond to the request.
• Delegate to the next handler in the chain.
• Insert more handlers in the chain and delegate to them.
Bad IO handlingpackage org.groovyando;
import ratpack.server.RatpackServer; import java.nio.file.Files; import java.nio.file.Paths;
public class Main { public static void main(String... args) throws Exception { RatpackServer.start(s -> s .handlers(chain -> chain .get(ctx -> { String fileContent = new String(Files .readAllBytes(Paths.get("build.gradle")));
ctx.render(fileContent); })) ); } }
Better IO Handlingpackage org.groovyando;
import ratpack.exec.Blocking; import ratpack.server.RatpackServer;
import java.nio.file.Files; import java.nio.file.Paths;
public class Main { public static void main(String... args) throws Exception { RatpackServer.start(s -> s .handlers(chain -> chain .get(ctx -> { Blocking.get(() -> new String(Files .readAllBytes(Paths.get("build.gradle")))) .then(data -> ctx.render(data)); })) ); } }
Better usage of Promises!package org.groovyando;
import ratpack.exec.Blocking; import ratpack.server.RatpackServer;
import java.nio.file.Files; import java.nio.file.Paths;
public class Main { public static void main(String... args) throws Exception { RatpackServer.start(s -> s .handlers(chain -> chain .get(ctx -> { ctx.render(Blocking.get(() -> new String(Files .readAllBytes(Paths.get("build.gradle"))))); })) ); } }
Promise Representation of a potential value.
Promise
• Returns a simple value
• Very different to RxJava
Using Promises
Promise .<String>of(downstream -> { //puedes regresar un valor downstream.success("valor de retorno"); //o puedes fallar downstream.error(new RuntimeException()); }) .onError(throwable -> System.out.print("error por acá")) .then(System.out::println);
Promises in Action!
Promise .<String>of(downstream -> { //puedes regresar un valor downstream.success("valor de retorno"); //o puedes fallar downstream.error(new RuntimeException()); downstream.complete(); }) .onError(throwable -> System.out.print("error por acá")) .map(s -> s.toLowerCase()) .flatMap(s -> Blocking.get(() -> "demo" + s).map(s1 -> s1.toLowerCase())) .cache() .then(System.out::println);
Promises are not a free lunch
1.You can not use the typical try/catch
2.What about ThreadLocal?
3.Most libs aren’t non blocking.
4.Debugging is a PITA (segmentation of stack traces)
Deal with the issues (1..3)
• Use ratpack.exec.Execution
try/catch
ratpack.exec.Execution.fork() .onError(throwable -> { //global errorHandler for this execution throwable.printStackTrace(); }) .start(execution -> { new String(Files.readAllBytes(Paths.get("build.gradle"))); });
Dealing with ThreadLocal
ratpack.exec.Execution.fork() .start(execution -> { Execution.current().add(Integer.class, 0);
Blocking .get(() -> Execution.current().get(Integer.class)) .then(System.out::println); });
Show me the code!
holagus.com