Share
Embed
Introducing JRuby
Given at Surrey Ruby Users Group in Guildford - Jan 2013
References other talks and videos throughout. Borrows benchmarks and material from the Torquebox team so apologies for the blatant plagiarism.
xavriley
January 29, 2013
Transcript
56 slides
-
He who does not know foreign languages, knows nothing of
his own - Goethe -
• WTF? Clear up FUD • Why? Advantages of JRuby
• How? Code Demo • When? Use cases -
WTF? The Ruby Programming Language on the JVM tracks MRI
1.9.3+ rubyspec.org fully tested CI server -
WTF? Java Virtual Machine • Java - write once, run
anywhere • Split into Java API, and JVM • Handles compatibility with host OS • 256 bytecodes*, Java standard classes • Exceptions, GC, memory and threads *of which, only 10 matter -
Why? What's wrong with MRI? • C extension API •
Inefficient GC* • GIL / no real threads / poor multicore • The “80/20” interpreter * (better in 2.0 and 1.9.3-perf) -
Why? What's wrong with processes? • Complete copy of app
= more memory • More “complex” • Communication is hard • Cars v train • 100 core CPUs - what then? 100 VMs? -
Why? What's wrong with processes? * However, they’re not all
bad. See Unicorn, Linux and Passenger for examples... -
Why? Scream if you want to go faster... Two options
1. Write your own VM eg. YARV, Rubinius 2.Use an existing VM JRuby, MagLev, IronRuby -
Why? Scream if you want to go faster... The JVM
•15 years engineering by whole teams • Free, Open Source • Fastest VM - comparable with C • Best GCs to choose from • All JVMs full parallel threaded • All platforms JRuby • started in 2001! • sponsored by RedHat • Free, Open Source • same memory model / threading as the JVM • Constantly refined for speed and efficiency -
Why? Scream if you want to go faster... The JVM
•15 years engineering by whole teams • Free, Open Source • Fastest VM - comparable with C • Best GCs to choose from • All JVMs full parallel threaded • All platforms JRuby • started in 2001! • sponsored by RedHat • Free, Open Source • same memory model / threading as the JVM • Constantly refined for speed and efficiency GoGaRuCo 2012- High Performance Ruby - Charles Nutter -
Why? But Ruby is slow... No, it’s not - but
the applications are “the way you write your code is far more important than the runtime” - Charles Nutter -
Why? But Ruby is slow... • Node - 3500 req/s
single process, single thread • Latest Padrino ( 0.11.0 ) ??? -
Why? But Ruby is slow... • Node - 3500 req/s
single process, single thread • Latest Padrino, ( 0.11.0 ) 3000 req/s -
Why? Benchmarks - Rails / Spree Torquebox - 6th Oct
2011 • TorqueBox on JRuby 1.6.4 • Trinidad 1.2.3 on JRuby 1.6.4 • Passenger 3.0.9 standalone on REE and Ruby 1.9.2 • Unicorn 4.1.1 on REE and Ruby 1.9.2 -
Why? Benchmarks - Rails / Spree It’s a shame that
the benchmarks are old 1.9.3-p194-perf and JRuby 1.7 .2 will be very different... -
How? Interop # This is the 'magical Java require line'.
require 'java' # With the 'require' above, we can now refer to things that are part of the # standard Java platform via their full paths. frame = javax.swing.JFrame.new("Window") # Creating a Java JFrame label = javax.swing.JLabel.new("Hello") # We can transparently call Java methods on Java objects, just as if they were defined in Ruby. frame.getContentPane.add(label) # Invoking the Java method 'getContentPane'. frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE) frame.pack frame.setVisible(true) -
How? Interop # This is the 'magical Java require line'.
require 'java' require 'path/to/mycode.jar' Java: org.foo.department.Widget Ruby: Java::OrgFooDepartment::Widget These two calls are equivalent java.lang.System.currentTimeMillis java.lang.System.current_time_millis x.getSomething becomes x.something x.setSomething(newValue) becomes x.something = new_value x.isSomething becomes x.something? JavaClass.new or JavaClass.new(x,y,z) generally works as expected -
How? Interop ~ 50,000 libraries on Maven Clojure, Scala, Python,
Javascript interop available too... -
Why? Torquebox Rack TorqueBox supports Rack, including Rails 2.3.x, Rails
3.x, Sinatra, and others. Rack applications are served as first-class resources within the web container. The web container is clusterable, and web sessions may be shared between nodes without any additional configuration. JDBC High-performance tried-and-true Java Database Connectivity (JDBC) database drivers power your ActiveRecord and other database access. Daemons TorqueBox provides the framework to manage your daemon-like Ruby components. TorqueBox makes sure it starts and stops with your application. What you do in the middle is up to you. Scheduled Jobs Cron-like functionality is provided by the TorqueBox server. Job classes implemented in Ruby have full access to to your Ruby environment and are managed by a durable job scheduler. Messaging Your simple Ruby components can both produce and consume messages from clustered and distributed asynchronous messaging fabric powered by HornetQ. Asynchronous Tasks Leveraging the messaging system, TorqueBox makes it easy to execute simple tasks and methods asynchronously, allows your application to quickly return control to the user. -
How? Torquebox - setup $ cd ~/torquebox_examples/rails_example $ torquebox rails
apply /Users/someone/torquebox-2.3.0/share/rails/template.rb gemfile torquebox (2.3.0) remove config/initializers/session_store.rb initializer session_store.rb initializer active_record_backgroundable.rb rakefile torquebox.rake -
How? Torquebox - background jobs class Post < ActiveRecord::Base attr_accessible
:body, :title after_create :publish_to_social_network always_background :publish_to_social_network def publish_to_social_network puts "Publishing '#{title}' to twitter" sleep(5) puts "Post published" end end -
How? Torquebox - built in cron --- # This is
the TorqueBox configuration file. Refer to the TorqueBox # documentation at http://torquebox.org/documentation/current/ # for all configuration options. web: context: "/" jobs: post_counter: job: PostCounter cron: "*/10 * * * * ?" ~/torquebox_examples/rails_example/config/torquebox.yml -
How? Torquebox - daemons class PostIdeaGrabber def initialize(options) @queue =
TorqueBox::Messaging::Queue.new(options['queue_name']) end def start puts "******** Starting PostIdeaGrabber ********" Thread.new do until @done @queue.publish("Random idea #{rand(100)}") sleep 2 end end end def stop @done = true end end -
How? Torquebox - built in cron --- # This is
the TorqueBox configuration file. Refer to the TorqueBox # documentation at http://torquebox.org/documentation/current/ # for all configuration options. web: context: "/" jobs: post_counter: job: PostCounter cron: "*/10 * * * * ?" services: post_idea_grabber: service: PostIdeaGrabber config: queue_name: "/queue/post_ideas" queues: /queue/post_ideas: durable: false ~/torquebox_examples/rails_example/config/torquebox.yml -
How? Torquebox - and the rest... • Infinispan caching •Built
in clustering •Distributed transactions -
How? Torquebox - and the rest... • Check out sample
app (“Poorsmatic”) • Watch “Deploy, scale and sleep at night” GoGaRuCo 2012 - Joe Kutner -
How? Diving in $ rvm get head $ rvm install
jruby $ gem install jruby-lint $ jrlint -
How? Diving in $ rvm get head $ rvm install
jruby $ gem install jruby-lint $ jrlint -
How? Diving in replace gems with jdbc equivalents declare pool
(configure postgres) “xa:false” for torquebox -
When? Java shop Performance sensitive Single Product Large infrastructure Complex
app (torquebox) now - just run jrlint -
PS Threads + concurrency - Celluloid, EM-Synchrony What about the
Heroku effect? Economics, worse-is-better etc. Is Ruby the right choice for parallel/concurrent apps?