jruby and torquebox
DESCRIPTION
TRANSCRIPT
Christopher Spring
+ =
Thursday 07 February 13
@autonomous
Thursday 07 February 13
Thursday 07 February 13
Thursday 07 February 13
“Java is a DSL for converting large XML files into Stack Traces”
@ davetron5000
Thursday 07 February 13
... and that’s all I have to say about that
Thursday 07 February 13
Thursday 07 February 13
Structure
Thursday 07 February 13
BytecodeJIT
JavaInteg
CoreClassesParser
jRuby
C APINative
JITGCThreads
JVM
Charles Nutter - Euroko2012Thursday 07 February 13
BytecodeJIT
JavaInteg
CoreClassesParser
jRuby
Charles Nutter - Euroko2012Thursday 07 February 13
“We could stop working on jRuby and it would continue to get faster.”
Charles Nutter - Euroko2012Thursday 07 February 13
Performance
Thursday 07 February 13
require 'benchmark'
def fib(n) return 1 if n < 2 fib(n - 2) + fib(n - 1)end
arr = []puts Benchmark.measure{ 40.times{ |i| arr << fib(i) }}puts arr.inspect# [1, 1, 2, 3, 5, 8, 13, 21, ... ]
Thursday 07 February 13
0
15
30
45
60
Time in seconds
52.8
Thursday 07 February 13
0
15
30
45
60
Time in seconds
52.8
10.4
Thursday 07 February 13
0
15
30
45
60
Time in seconds
52.8
10.4
REE - 183.8
Thursday 07 February 13
get '/' do 1_000.times do MultiJson.encode({ one: 'one', date: Date.today, two: 2 }) endend
# ruby jsonator.rb -s Puma
Thursday 07 February 13
ab -n 1000 -c 32 http://localhost:4567/
Thursday 07 February 13
Thursday 07 February 13
0
7,5
15
22,5
30
Time in seconds
24.946
Thursday 07 February 13
Thursday 07 February 13
0
7,5
15
22,5
30
Time in seconds
24.946
8.489
Thursday 07 February 13
Thursday 07 February 13
0
7,5
15
22,5
30
Time in seconds
24.946
2.892
8.489
Thursday 07 February 13
Runtime optimizations
Thursday 07 February 13
method_one method_two method_three
Thursday 07 February 13
method_one method_two method_three
Thursday 07 February 13
Threading
Thursday 07 February 13
vs.
Thursday 07 February 13
• No GIL
• Native threads
• One process for all cores
Thursday 07 February 13
Concurrency threshold
100 process system
100 thread system
vs.
Thursday 07 February 13
Java Libraries
Thursday 07 February 13
<html><head> <style type="text/css"> body{ font-family: sans-serif; text-align: center; background-color: #efefef; } h1{ color: blue; font-weight: bold;} div{ border: 4px dashed red; padding: 2em;margin: 2em; } </style> </head> <body> <h1>PDFs with Flying Saucer and jRuby</h1> <div> <p>I'm a lumberjack, and I'm ok...</p> <img src="flower.jpeg"></img> </div> </body></html>
Thursday 07 February 13
require 'stringio'require 'itext'require 'flying_saucer'
io = StringIO.newcontent = File.read('example.html')
renderer = org.xhtmlrenderer.pdf.ITextRenderer.newrenderer.set_document_from_string(content)renderer.layoutrenderer.create_pdf(io.to_outputstream)
File.write('pdf_result.pdf', io.string)
Thursday 07 February 13
html
Thursday 07 February 13
Thursday 07 February 13
A loads more....!!!
• Choice of GC
• Cross platform
• GUI apps
• Great tooling
• Massive ecosystem
Thursday 07 February 13
Thursday 07 February 13
Let’s take a step back...
Thursday 07 February 13
Your App
Thursday 07 February 13
Your App
BackgroundJobs
Thursday 07 February 13
Your App
BackgroundJobs
Thursday 07 February 13
Your App
BackgroundJobs
ScheduledJobs
Thursday 07 February 13
Your App
BackgroundJobs
ScheduledJobs
Cron
Thursday 07 February 13
Thursday 07 February 13
TorqueBox
Thursday 07 February 13
TorqueBox
Thursday 07 February 13
TorqueBox
App1
App2
App3
Thursday 07 February 13
TorqueBox
App1
App2
App3
Thursday 07 February 13
TorqueBox
App1App2App3
BackgroundTasks
ScheduledTasks
Long runningservices
Async. Messages
Thursday 07 February 13
TorqueBox
App1App2App3
BackgroundTasks
ScheduledTasks
Long runningservices
Async. Messages
JBoss AS
Clustering Load balancing High availability
Thursday 07 February 13
Some of the toys...
• HornetQ
• Infinispan
• Quartz Scheduler
Thursday 07 February 13
Thursday 07 February 13
It’s still justbusiness as usual
Thursday 07 February 13
AsynchronousStuffs
Thursday 07 February 13
class Charge < ActiveRecord::Base # id :integer not null, primary key # cents :integer default(0) # state :string(255) default("pending")end
Thursday 07 February 13
class Charge < ActiveRecord::Base # id :integer not null, primary key # cents :integer default(0) # state :string(255) default("pending")end
Thursday 07 February 13
class Charge < ActiveRecord::Base # id :integer not null, primary key # cents :integer default(0) # state :string(255) default("pending")end
Thursday 07 February 13
class Charge < ActiveRecord::Base # id :integer not null, primary key # cents :integer default(0) # state :string(255) default("pending")end
Thursday 07 February 13
class Charge < ActiveRecord::Base # id :integer not null, primary key # cents :integer default(0) # state :string(255) default("pending")end
Thursday 07 February 13
class ChargesController < ActionController::Base include TorqueBox::Injectors def create @charge = Charge.create( params[:charge] ) msg = 'Slaves turtles doing thy bidding' redirect_to( charges_url, notice: msg ) endend
fetch('/queue/charges').publish( @charge.id )
Thursday 07 February 13
class ChargesController < ActionController::Base include TorqueBox::Injectors def create @charge = Charge.create( params[:charge] ) msg = 'Slaves turtles doing thy bidding' redirect_to( charges_url, notice: msg ) endend
fetch('/queue/charges').publish( @charge.id )
Thursday 07 February 13
class ChargesController < ActionController::Base include TorqueBox::Injectors def create @charge = Charge.create( params[:charge] ) msg = 'Slaves turtles doing thy bidding' redirect_to( charges_url, notice: msg ) endend
fetch('/queue/charges').publish( @charge.id )
'/queue/charges' ChargeProcessor
Thursday 07 February 13
fetch('/queue/charges').publish( @charge.id )
# config/torquebox.rbTorqueBox.configure do
queue '/queue/charges' do processor ChargeProcessor end
end
Thursday 07 February 13
# app/processors/charge_processor.rbclass ChargeProcessor < TorqueBox::Messaging::MessageProcessor def on_message( charge_id ) # ... end def on_error( exception ) # optionally deal with exception # ... endend
Thursday 07 February 13
# app/processors/charge_processor.rbclass ChargeProcessor < TorqueBox::Messaging::MessageProcessor def on_message( charge_id ) @charge = Charge.find( charge_id ) result = PaymentGateway.process( @charge ) generate_receipt if result.success? broadcast_status end
end
Thursday 07 February 13
# app/processors/charge_processor.rbclass ChargeProcessor < TorqueBox::Messaging::MessageProcessor def on_message( charge_id ) @charge = Charge.find( charge_id ) result = PaymentGateway.process( @charge ) generate_receipt if result.success? broadcast_status end
end
def generate_receipt fetch('queue/receipts').publish( @charge.id ) end
Thursday 07 February 13
# app/processors/charge_processor.rbclass ChargeProcessor < TorqueBox::Messaging::MessageProcessor def on_message( charge_id ) @charge = Charge.find( charge_id ) result = PaymentGateway.process( @charge ) generate_receipt if result.success? broadcast_status end
end
def generate_receipt fetch('queue/receipts').publish( @charge.id ) end
def broadcast_status fetch('topics/charge_status').publish( @charge.id )end
Thursday 07 February 13
Queue
Topic
Processor
Processor
Processor
Processor
Thursday 07 February 13
# config/torquebox.rbTorqueBox.configure do queue '/queue/charges' do # processors/charge_processor.rb processor ChargeProcessor end topic '/topic/charge_status' do processor StatusProcessor processor TesterProcessor processor AlertAdminProcessor endend
Thursday 07 February 13
And WebSockets?
Thursday 07 February 13
Hells yes!!
Thursday 07 February 13
Topic/Queue
Processor
Stomplet
Client
Thursday 07 February 13
Topic/Queue
Processor
Stomplet
Client
‘/stomp/statuses’
Thursday 07 February 13
Topic/Queue
Processor
Stomplet
Client
‘/stomp/statuses’‘/topics/charge_status’
Thursday 07 February 13
# config/torquebox.rbstomplet ChargeStatusStomplet do route '/stomp/status'end
Thursday 07 February 13
# app/stomplets/charge_status_stompletclass ChargeStatusStomplet < TorqueBox::Stomp::JmsStomplet def on_subscribe( client ) topic = destination_for('/topics/charge_status', :topic) subscribe_to( client , topic ) end # configure(config) # destroy() # on_subscribe(subscriber) # on_unsubscribe(subscriber) # on_message(message)end
Thursday 07 February 13
javascript_include_tag '/stilts-stomp'
Thursday 07 February 13
var stompUrl = '#{stomp_url}'
$( function() { if (stompUrl) { var client = Stomp.client(stompUrl);
client.connect( username, password, function() { client.subscribe( '/stomp/status', function(msg) { alert(msg.body); }); }); }});
module ApplicationHelper include TorqueBox::Injectors def stomp_url inject('stomp-endpoint') endend
Thursday 07 February 13
Thursday 07 February 13
Thursday 07 February 13
Thanks for Listening!
Thursday 07 February 13
Questions?
Thursday 07 February 13