Slide 1

Slide 1 text

Reactive Ruby

Slide 2

Slide 2 text

Reactive Ruby - web apps with JRuby and Ratpack -

Slide 3

Slide 3 text

max

Slide 4

Slide 4 text

max ! klappradla " klappradla

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

limits

Slide 9

Slide 9 text

$ GIL

Slide 10

Slide 10 text

blocking IO

Slide 11

Slide 11 text

client server db

Slide 12

Slide 12 text

client server db ⏳ ⏳

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

non-blocking IO

Slide 15

Slide 15 text

client server db

Slide 16

Slide 16 text

client server db ⏳

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

“…gain the performance and concurrency benefits of Java without writing any Java code or XML” -joe kutner-

Slide 21

Slide 21 text

# ratpack.io

Slide 22

Slide 22 text

“It is built on Java 8, Netty and reactive principles" # netty.io -ratpack.io-

Slide 23

Slide 23 text

“It provides just enough for writing practical, high performance, apps.” -ratpack.io-

Slide 24

Slide 24 text

#reactive )

Slide 25

Slide 25 text

“So let's cut the bullshit.
 Reactive programming is programming with asynchronous data streams” - @andrestaltz- # The introduction to Reactive Programming you've been missing

Slide 26

Slide 26 text

iterator ♻ + observer +

Slide 27

Slide 27 text

“non-blocking communication allows recipients to only consume resources while active, leading to less system overhead” - reactivemanifesto- # reactivemanifesto.org

Slide 28

Slide 28 text

# reactivex.io/ Rx* libs ,

Slide 29

Slide 29 text

# Get evens and square each some_source .select { |x| x.even? } .map { |x| x * x } .subscribe { |x| puts x.to_s } # github.com/ReactiveX/RxRuby

Slide 30

Slide 30 text

ratpack -

Slide 31

Slide 31 text

public class Main { public static void main(String... args) throws Exception { RatpackServer.start(server -> server .handlers(chain -> chain .get(ctx -> ctx.render("Hello World")) ) ); } } # ratpack.io/manual/current/launching.html#launching

Slide 32

Slide 32 text

# Gemfile gem 'jbundler' # Jarfile jar 'io.ratpack:ratpack-core', '1.4.0' jar 'org.slf4j:slf4j-simple', '1.7.20'

Slide 33

Slide 33 text

$ bundle install

Slide 34

Slide 34 text

$ bundle exec jbundle install

Slide 35

Slide 35 text

# github.com/klappradla/jruby_ratpack_examples/hello_world require 'java' require 'jruby/core_ext' require 'bundler/setup' Bundler.require java_import 'ratpack.server.RatpackServer' RatpackServer.start do |server| server.handlers do |chain| chain.get do |ctx| ctx.render('Hello World from Ratpack / JRuby') end end end

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

blocking IO ?

Slide 38

Slide 38 text

“A promise is a representation of a value which will become available later. Methods such as map(Function) […] allow a pipeline of “operations” to be specified, that the value will travel through as it becomes available.” -ratpack docs- # ratpack.io/manual/current/api/ratpack/exec/Promise.html

Slide 39

Slide 39 text

# ratpack.io/manual/current/async.html#performing_blocking_operations_eg_io java_import 'ratpack.server.RatpackServer' java_import 'ratpack.exec.Blocking' require 'json' RatpackServer.start do |server| server.handlers do |chain| chain.get('music') do |ctx| Blocking .get { DB[:albums].all } .then { |data| ctx.render(JSON.dump(data))} end end end

Slide 40

Slide 40 text

RatpackServer.start do |server| server.handlers do |chain| chain.get('music') do |ctx| Blocking .get { DB[:albums].all } .then { |data| ctx.render(JSON.dump(data))} end end end

Slide 41

Slide 41 text

RatpackServer.start do |server| server.handlers do |chain| chain.get('music') do |ctx| Blocking .get { DB[:albums].all } .map { |data| JSON.dump(data) } .then { |data| ctx.render(data)} end end end

Slide 42

Slide 42 text

non-blocking HTTP ?

Slide 43

Slide 43 text

class Server def self.run RatpackServer.start do |server| server.handlers do |chain| chain.all(RequestLogger.ncsa) chain.get('music', Handler::Music) chain.get('planets', Handler::Planets) chain.all(Handler::NotFound) end end end end # github.com/klappradla/jruby_ratpack_examples/http_example

Slide 44

Slide 44 text

# github.com/klappradla/jruby_ratpack_examples/http_example module Handler class Base def self.handle(ctx) new(ctx).handle end def initialize(ctx) @ctx = ctx end attr_reader :ctx def handle raise NotImplementedError end end end

Slide 45

Slide 45 text

# github.com/klappradla/jruby_ratpack_examples/http_example java_import 'ratpack.http.client.HttpClient' require_relative 'base' module Handler class Planets < Base URL = java.net.URI.new('http://swapi.co/api/planets') def handle ctx .get(HttpClient.java_class) .get(URL) .map { |resp| resp.get_body } .map { |body| body.get_text } .then { |data| render(data) } end private def render(data) resp = ctx.get_response header = 'application/json;charset=UTF-8' resp.send(header, data) end end end

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

# github.com/klappradla/jruby_ratpack_examples/sinatra

Slide 48

Slide 48 text

# github.com/klappradla/jruby_ratpack_examples/benchmarks # Sinatra Running 30s test @ http://localhost:5050 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 284.63ms 358.37ms 1.95s 85.07% Req/Sec 145.18 72.13 434.00 65.54% 16392 requests in 30.08s, 64.94MB read Socket errors: connect 0, read 0, write 0, timeout 72 Non-2xx or 3xx responses: 1 Requests/sec: 545.00 Transfer/sec: 2.16MB # Ratpack Running 30s test @ http://localhost:5050 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 150.36ms 228.64ms 1.86s 88.18% Req/Sec 338.10 129.48 710.00 71.18% 32746 requests in 30.08s, 127.09MB read Requests/sec: 1088.56 Transfer/sec: 4.22MB

Slide 49

Slide 49 text

# github.com/klappradla/jruby_ratpack_examples/benchmarks # Sinatra Running 30s test @ http://localhost:5050 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 284.63ms 358.37ms 1.95s 85.07% Req/Sec 145.18 72.13 434.00 65.54% 16392 requests in 30.08s, 64.94MB read Socket errors: connect 0, read 0, write 0, timeout 72 Non-2xx or 3xx responses: 1 Requests/sec: 545.00 Transfer/sec: 2.16MB # Ratpack Running 30s test @ http://localhost:5050 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 150.36ms 228.64ms 1.86s 88.18% Req/Sec 338.10 129.48 710.00 71.18% 32746 requests in 30.08s, 127.09MB read Requests/sec: 1088.56 Transfer/sec: 4.22MB

Slide 50

Slide 50 text

# github.com/jruby/jruby/wiki/AboutJRuby # github.com/klappradla/jruby_ratpack_examples # blog.heroku.com/reactive_ruby_building_real_time_apps_with_jruby_and_ratpack