Pro Yearly is on sale from $80 to $50! »

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. Reactive Ruby

  2. Reactive Ruby - web apps with JRuby and Ratpack -

  3. max

  4. max ! klappradla " klappradla

  5. None
  6. None
  7. None
  8. limits

  9. $ GIL

  10. blocking IO

  11. client server db

  12. client server db ⏳ ⏳

  13. None
  14. non-blocking IO

  15. client server db

  16. client server db ⏳

  17. None
  18. None
  19. None
  20. “…gain the performance and concurrency benefits of Java without writing

    any Java code or XML” -joe kutner-
  21. # ratpack.io

  22. “It is built on Java 8, Netty and reactive principles"

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

    -ratpack.io-
  24. #reactive )

  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
  26. iterator ♻ + observer +

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

    leading to less system overhead” - reactivemanifesto- # reactivemanifesto.org
  28. # reactivex.io/ Rx* libs ,

  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
  30. ratpack -

  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
  32. # Gemfile gem 'jbundler' # Jarfile jar 'io.ratpack:ratpack-core', '1.4.0' jar

    'org.slf4j:slf4j-simple', '1.7.20'
  33. $ bundle install

  34. $ bundle exec jbundle install

  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
  36. None
  37. blocking IO ?

  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
  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
  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
  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
  42. non-blocking HTTP ?

  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
  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
  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
  46. None
  47. # github.com/klappradla/jruby_ratpack_examples/sinatra

  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
  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
  50. # 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