Reactive Ruby - building web apps with JRuby and Ratpack

Reactive Ruby - building web apps with JRuby and Ratpack

Slides for my talk about reactive Ruby and building high performant web apps with JRuby and Ratpack.io at the RUG::B meetup 2017/03.

F85cfa2c6c69d94bc48ece99b7b2cb59?s=128

Max Mulatz

March 02, 2017
Tweet

Transcript

  1. 3.

    max

  2. 5.
  3. 6.
  4. 7.
  5. 8.
  6. 9.
  7. 13.
  8. 17.
  9. 18.
  10. 19.
  11. 25.

    “So let's cut the bullshit.
 Reactive programming is programming with

    asynchronous data streams” - @andrestaltz- # The introduction to Reactive Programming you've been missing
  12. 27.

    “non-blocking communication allows recipients to only consume resources while active,

    leading to less system overhead” - reactivemanifesto- # reactivemanifesto.org
  13. 29.

    # 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
  14. 30.
  15. 31.

    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
  16. 35.

    # 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
  17. 36.
  18. 38.

    “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
  19. 39.

    # 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
  20. 40.

    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
  21. 41.

    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
  22. 43.

    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
  23. 44.

    # 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
  24. 45.

    # 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
  25. 46.
  26. 48.

    # 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
  27. 49.

    # 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