30
Ratpack @jvm_mx Meetup / CDMX / February 2016

Ratpack JVM_MX Meetup February 2016

Embed Size (px)

Citation preview

Page 1: Ratpack JVM_MX Meetup February 2016

Ratpack@jvm_mx Meetup / CDMX / February 2016

Page 2: Ratpack JVM_MX Meetup February 2016
Page 3: Ratpack JVM_MX Meetup February 2016

Ratpack

Page 4: Ratpack JVM_MX Meetup February 2016
Page 5: Ratpack JVM_MX Meetup February 2016

Ratpack

• Originally written in Groovy

• Now a Java 8 code base project.

• It uses Apache Netty

• Apache 2.0 Licensed

• Fully Groovy support!

Page 6: Ratpack JVM_MX Meetup February 2016

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!" } } }

Page 7: Ratpack JVM_MX Meetup February 2016

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'

Page 8: Ratpack JVM_MX Meetup February 2016

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.

Page 9: Ratpack JVM_MX Meetup February 2016

Ratpack key features

• Strongly typed

• Non blocking

Page 10: Ratpack JVM_MX Meetup February 2016

What is blocking?

Page 11: Ratpack JVM_MX Meetup February 2016

Blocking

• Any IO operation

• InputStream

• Lock.lock()

• JDBC

• 99% of all APIs out there!!

Page 12: Ratpack JVM_MX Meetup February 2016

Contention = threads > cores

Page 13: Ratpack JVM_MX Meetup February 2016

Blocking and threadsEach concurrent piece of

work requires a separate thread.

100 concurrent requests =~ 100 threads

Page 14: Ratpack JVM_MX Meetup February 2016

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.

Page 15: Ratpack JVM_MX Meetup February 2016

Ratpack components

• Launch Configuration

• Handlers

• Registry

Page 16: Ratpack JVM_MX Meetup February 2016

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.

Page 17: Ratpack JVM_MX Meetup February 2016

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.

Page 18: Ratpack JVM_MX Meetup February 2016

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); })) ); } }

Page 19: Ratpack JVM_MX Meetup February 2016

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)); })) ); } }

Page 20: Ratpack JVM_MX Meetup February 2016

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"))))); })) ); } }

Page 21: Ratpack JVM_MX Meetup February 2016

Promise Representation of a potential value.

Page 22: Ratpack JVM_MX Meetup February 2016

Promise

• Returns a simple value

• Very different to RxJava

Page 23: Ratpack JVM_MX Meetup February 2016

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);

Page 24: Ratpack JVM_MX Meetup February 2016

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);

Page 25: Ratpack JVM_MX Meetup February 2016

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)

Page 26: Ratpack JVM_MX Meetup February 2016

Deal with the issues (1..3)

• Use ratpack.exec.Execution

Page 27: Ratpack JVM_MX Meetup February 2016

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"))); });

Page 28: Ratpack JVM_MX Meetup February 2016

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); });

Page 29: Ratpack JVM_MX Meetup February 2016

Show me the code!

Page 30: Ratpack JVM_MX Meetup February 2016

holagus.com