Torquebox OSCON Java 2011

101
OSCON Java July 2011 Creative Commons BY SA 3.0 Toby Crawley The Beauty of Ruby with the Power of Java

description

 

Transcript of Torquebox OSCON Java 2011

Page 1: Torquebox OSCON Java 2011

OSCON JavaJuly 2011

Creative Commons BY-­SA 3.0

Toby Crawley

The Beauty of Ruby with the Power of Java

Page 2: Torquebox OSCON Java 2011

• @tcrawley

• TorqueBox Core Developer

• Red Hat Senior Engineer

Toby Crawley

!

Page 3: Torquebox OSCON Java 2011

but it's a team.

Page 4: Torquebox OSCON Java 2011

What is TorqueBox?

The mating of JRuby to JBoss AS.

Page 5: Torquebox OSCON Java 2011
Page 6: Torquebox OSCON Java 2011

Application Server?

Rails

Rack

Sinatra

Apache/Nginx

Passenger/Thin

Page 7: Torquebox OSCON Java 2011

Application Server?

Rails

Rack

Sinatra

Apache/Nginx

Passenger/ThinResque/

DelayedJob

Tasks

Page 8: Torquebox OSCON Java 2011

Application Server?

Rails

Rack

Sinatra

Apache/Nginx

Passenger/Thin

crond

JobsResque/

DelayedJob

Tasks

Page 9: Torquebox OSCON Java 2011

Application Server?

Rails

Rack

Sinatra

Apache/Nginx

Passenger/Thin

crond

JobsResque/

DelayedJob

Tasks

god/monit

Daemons

Page 10: Torquebox OSCON Java 2011

Rails

Rack

Sinatra

ProcsTasks DaemonsJobs

HAClustering Load Balancing

JBoss ASWeb Messaging Scheduling Services

TorqueBox AS

Page 11: Torquebox OSCON Java 2011

Goals• Support Ruby web frameworks• Rails• Sinatra• Rack

Page 12: Torquebox OSCON Java 2011

Goals• Support Ruby web frameworks• Rails• Sinatra• Rack

• Go beyond the web• Messaging• Jobs• Services

Page 13: Torquebox OSCON Java 2011

Goals

No XML, No Java(unless you're into that sort of thing)

Page 14: Torquebox OSCON Java 2011

Why Ruby?

• No compilation

• Highly expressive

• Lots of shiny frameworks

• Few specifications (more fun!)

• Meta-­programming

Page 15: Torquebox OSCON Java 2011

com/foo/Anything.java

Set<Person> people = new HashSet<Person>();;

for ( Team each : teams ) people.addAll( each.getMembers() );;

for ( Person each : people ) each.promote();;

Expressive

Page 16: Torquebox OSCON Java 2011

anything.rb

teams.collect(&:members). flatten.uniq.each(&:promote)

Expressive

Page 17: Torquebox OSCON Java 2011

anything.rb

all_members = teams.collect(&:members)

all_members.flatten!.uniq!

all_members.each(&:promote)

Expressive

Page 18: Torquebox OSCON Java 2011

Why JRuby?

Page 19: Torquebox OSCON Java 2011

Why JRuby?

system = Java::java.lang.System

system.properties.each do |k,v| system.properties[k] = v.upcaseend

Page 20: Torquebox OSCON Java 2011

Why JRuby?

• Very fast runtime

• Real threads

• Java libraries

• Java tools

• Healthy community

Page 21: Torquebox OSCON Java 2011

TorqueBox Details

Builds upon and requires JBoss AS 6.x.

Tight integration with the JBoss stack.

Page 22: Torquebox OSCON Java 2011

Easy Install

(download 1.1 from torquebox.org)

$ unzip torquebox-­dist-­1.1-­bin.zip

$ export TORQUEBOX_HOME=$PWD/torquebox-­1.1$ export JBOSS_HOME=$TORQUEBOX_HOME/jboss$ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

$ export PATH=$JRUBY_HOME/bin:$PATH

Page 23: Torquebox OSCON Java 2011

Easy Install

(download 1.1 from torquebox.org)

$ unzip torquebox-­dist-­1.0.0-­bin.zip

$ export TORQUEBOX_HOME=$PWD/torquebox-­1.1$ export JBOSS_HOME=$TORQUEBOX_HOME/jboss$ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

$ export PATH=$JRUBY_HOME/bin:$PATH

Page 24: Torquebox OSCON Java 2011

Easy Install

(download 1.1 from torquebox.org)

$ unzip torquebox-­dist-­1.1-­bin.zip

$ export TORQUEBOX_HOME=$PWD/torquebox-­1.1$ export JBOSS_HOME=$TORQUEBOX_HOME/jboss$ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

$ export PATH=$JRUBY_HOME/bin:$PATH

Page 25: Torquebox OSCON Java 2011

Easy Install

(download 1.1 from torquebox.org)

$ unzip torquebox-­dist-­1.1-­bin.zip

$ export TORQUEBOX_HOME=$PWD/torquebox-­1.1$ export JBOSS_HOME=$TORQUEBOX_HOME/jboss$ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

$ export PATH=$JRUBY_HOME/bin:$PATH

Page 26: Torquebox OSCON Java 2011

Easy Install

(download 1.1 from torquebox.org)

$ unzip torquebox-­dist-­1.0.0.CR1-­bin.zip

$ export TORQUEBOX_HOME=$PWD/torquebox-­1*$ export JBOSS_HOME=$TORQUEBOX_HOME/jboss$ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

$ export PATH=$JRUBY_HOME/bin:$PATH

Make sure the jruby found in your path is in $JRUBY_HOME/bin.

Page 27: Torquebox OSCON Java 2011

Easy Install

(download 1.1 from torquebox.org)

$ unzip torquebox-­dist-­1.0.0.CR1-­bin.zip

$ export TORQUEBOX_HOME=$PWD/torquebox-­1*$ export JBOSS_HOME=$TORQUEBOX_HOME/jboss$ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

$ export PATH=$JRUBY_HOME/bin:$PATH

Make sure the jruby found in your path is in $JRUBY_HOME/bin.

Page 28: Torquebox OSCON Java 2011

Deployment

rake torquebox:run Run TorqueBox server

rake torquebox:deploy[context_path] Deploy the app in the current directory

rake torquebox:undeploy Undeploy the app in the current directory

Page 29: Torquebox OSCON Java 2011

Deployment

The torquebox:deploy task creates:

$TORQUEBOX_HOME/apps/my-­app.yml

Page 30: Torquebox OSCON Java 2011
Page 31: Torquebox OSCON Java 2011

Web

Run Ruby web-­apps within the context of the Servlet container.

Without compilation.

Page 32: Torquebox OSCON Java 2011

But continue editing

Continue live-­editing of running app:

models,views, controllers...

Page 33: Torquebox OSCON Java 2011

Non-­surprising. Almost boring.

Page 34: Torquebox OSCON Java 2011

Web (Session Integration)

class SomeController

def index session[:password] = 'sw0rdfish' end

end

Page 35: Torquebox OSCON Java 2011

Web (Session Integration)

public class SomeServlet public void doGet(HttpServletRequest request, HttpServletResponse resp)

request.getSession().getValue("password");;

Page 36: Torquebox OSCON Java 2011

Clustering

Ruby applications participate fully in AS clustering.

Can use JBoss mod_cluster.

Page 37: Torquebox OSCON Java 2011

mod_clusterA reverse proxy implemented as an Apache module with JBoss awareness.

Constantly gathers load statistics and deployment availability for intelligent request distribution.

Page 38: Torquebox OSCON Java 2011

Let's go beyond the

web...

Page 39: Torquebox OSCON Java 2011
Page 40: Torquebox OSCON Java 2011

app/jobs/newsletter_sender.rb

class NewsletterSender def run() subscriptions = Subscription.find(:all) subscriptions.each do |e| send_newsletter(e) end end end

Jobs

Page 41: Torquebox OSCON Java 2011

config/torquebox.yml

jobs: monthly_newsletter: description: first of month job: NewsletterSender cron: ‘0 0 0 1 * ?’

process_tps_reports: job: TPSReportProcessor cron: ‘0 0 0 0 MON ?’ singleton: true

Jobs

Page 42: Torquebox OSCON Java 2011
Page 43: Torquebox OSCON Java 2011

Regular Class

class Something

def foo end

def bar end

end

Page 44: Torquebox OSCON Java 2011

Blocking invocations

something = Something.new

something.foo

something.bar

Page 45: Torquebox OSCON Java 2011

Backgroundable

class Something

include TorqueBox::Messaging::Backgroundable

def foo end

def bar end

end

Page 46: Torquebox OSCON Java 2011

Explicitly Non-­blocking

something = Something.new

something.background.foo

something.background.bar

Page 47: Torquebox OSCON Java 2011

Choices

class Something

include TorqueBox::Messaging::Backgroundable always_background :foo

def foo end

def bar end

end

Page 48: Torquebox OSCON Java 2011

Implicitly Non-­blocking

something = Something.new

something.foo

Page 49: Torquebox OSCON Java 2011

See The Future

something = Something.new

future = something.foo

Page 50: Torquebox OSCON Java 2011

See The Future

future.started?

future.complete?

future.error?

future.result

Page 51: Torquebox OSCON Java 2011

See The Future

class Something

def foo ... count += 1 future.status = count ... end

end

Page 52: Torquebox OSCON Java 2011

See The Future

# on the 'client' side

future.status_changed?

future.status # => 42

Page 53: Torquebox OSCON Java 2011
Page 54: Torquebox OSCON Java 2011

Messaging

• JMS behind the scenes

•HornetQ is the JBoss JMS implementation

Page 55: Torquebox OSCON Java 2011

config/torquebox.yml

Destinations

queues: /queues/questions: /queues/answers: durable: falsetopics: /topics/new_accounts /topics/notifications

Page 56: Torquebox OSCON Java 2011

app/models/print_handler.rb

Processors

include TorqueBox::Messaging

class PrintHandler < MessageProcessor def initialize(opts) @printer = opts['printer'] || default end def on_message(body) puts "Processing #body of #message" endend

Page 57: Torquebox OSCON Java 2011

config/torquebox.yml

Processors

messaging: /topics/orders: - PrintHandler - ShoutHandler /queues/receipts: PrintHandler: concurrency: 5 config: printer: the_little_one

Page 58: Torquebox OSCON Java 2011

contrived example

Queues

questions = Queue.new('/queues/questions')answers = Queue.new('/queues/answers') Thread.new do questions.publish( "What time is it?" ) puts answers.receive( :timeout => 1000 )end puts questions.receiveanswers.publish( Time.now )

Page 59: Torquebox OSCON Java 2011

contrived example

Queues

questions = Queue.new('/queues/questions')answers = Queue.new('/queues/answers') Thread.new do questions.publish( "What time is it?" ) puts answers.receive( :timeout => 1000 )end puts questions.receiveanswers.publish( Time.now )

Page 60: Torquebox OSCON Java 2011

contrived example

Queues

questions = Queue.new('/queues/questions')answers = Queue.new('/queues/answers') Thread.new do questions.publish( "What time is it?" ) puts answers.receive( :timeout => 1000 )end puts questions.receiveanswers.publish( Time.now )

Page 61: Torquebox OSCON Java 2011

contrived example

Queues

questions = Queue.new('/queues/questions')answers = Queue.new('/queues/answers') Thread.new do questions.publish( "What time is it?" ) puts answers.receive( :timeout => 1000 )end puts questions.receiveanswers.publish( Time.now )

Page 62: Torquebox OSCON Java 2011

“on the fly”

Queues

include TorqueBox::Messaging

queue = Queue.new('/queues/foo')queue.create ... queue.destroy

Page 63: Torquebox OSCON Java 2011

Topics

• behavior is different, but interface is the same.

• all subscribers of a topic see each message, but only one subscriber will see any message from a queue

• use TorqueBox::Messaging::Topic

Page 64: Torquebox OSCON Java 2011
Page 65: Torquebox OSCON Java 2011

Services

Long-­running, non-­web “daemons” that share the runtime environment and deployment lifecycle of your app.

Page 66: Torquebox OSCON Java 2011

Services

• Represented as a class with optional initialize(Hash), start() and stop() methods, which should each return quickly.

• Typically will start a long-­running loop in a thread and respond to external events.

Page 67: Torquebox OSCON Java 2011

config/torquebox.yml

Services

services: TimeMachine: queue: /queue/morris_day

IrcBot: server: freenode.net channel: #torquebox publish: /topics/irc singleton: true

Page 68: Torquebox OSCON Java 2011

app/services/time_machine.rb

Services

class TimeMachine def initialize(opts) @queue = Queue.new(opts['queue']) end

def start Thread.new run end

def stop @done = true endend

Page 69: Torquebox OSCON Java 2011

app/services/time_machine.rb

Services

class TimeMachine def initialize(opts) @queue = Queue.new(opts['queue']) end

def start Thread.new run end

def stop @done = true endend

Page 70: Torquebox OSCON Java 2011

app/services/time_machine.rb

Services

class TimeMachine def initialize(opts) @queue = Queue.new(opts['queue']) end

def start Thread.new run end

def stop @done = true endend

Page 71: Torquebox OSCON Java 2011

app/services/time_machine.rb

Services

class TimeMachine def initialize(opts) @queue = Queue.new(opts['queue']) end

def start Thread.new run end

def stop @done = true endend

Page 72: Torquebox OSCON Java 2011

app/services/time_machine.rb

Services

class TimeMachine

def run until @done @queue.publish(Time.now) sleep(1) end end

end

Page 73: Torquebox OSCON Java 2011

app/services/time_machine.rb

Services

class TimeMachine

def run until @done @queue.publish(Time.now) sleep(1) end end

end

Page 74: Torquebox OSCON Java 2011
Page 75: Torquebox OSCON Java 2011

Caching

Integration with JBoss Infinispan, a distributed/replicated object store.

Page 76: Torquebox OSCON Java 2011

Transparent Infinispan

Easily used for all of the implicit caching within Rails.

Replace in-­memory, or memcached caches.

Page 77: Torquebox OSCON Java 2011

Opaque Infinispan

include ActiveSupport::Cache

myCache = TorqueBoxStore.new(:name => 'MyCache', :mode => :replicated, :sync => true)

Page 78: Torquebox OSCON Java 2011
Page 79: Torquebox OSCON Java 2011

Injection?

Letting the container figure out how to help you wire up complex component models.

Page 80: Torquebox OSCON Java 2011

aka

Inversion of Control

Guice, PicoContainer, JBoss Microcontainer

Page 81: Torquebox OSCON Java 2011

Java CDI

package com.mycorp;;

@ApplicationScopedclass Something @Inject private SomethingElse elsewise;;

@ApplicationScopedclass SomethingElse

Page 82: Torquebox OSCON Java 2011

CDI Injection

class MyService include TorqueBox::Injectors

def initialize opts= @thing = inject(com.mycorp.Something) endend

Page 83: Torquebox OSCON Java 2011

But there's more than just CDI you can inject. There's also queues, topics, heroin and other things.

Page 84: Torquebox OSCON Java 2011

Destination Injection

class MyService include TorqueBox::Injectors

def initialize opts= @inbound = inject("/topics/questions") @outbound = inject("/queues/answers") endend

Page 85: Torquebox OSCON Java 2011

JNDI Injection

class MyService include TorqueBox::Injectors

def initialize opts= @factory = inject("java:comp/env/jdbc/myDS") endend

Page 86: Torquebox OSCON Java 2011

JBossMC Injection

class MyService include TorqueBox::Injectors

def initialize opts= @heroin = inject("SomeMCBean") endend

Page 87: Torquebox OSCON Java 2011

Why MC Beans?All internal plumbing of JBoss AS is stitched together using MC.

Grab the WebServer, the CacheManager, whatevs.

Page 88: Torquebox OSCON Java 2011
Page 89: Torquebox OSCON Java 2011

BENchmarksReal-­world Rail application:

RedmineComparisons:

TorqueBox, Trinidad, Glassfish, Passenger, Unicorn, ThinRuntimes:

JRuby, MRI, RubyEE

Page 90: Torquebox OSCON Java 2011
Page 91: Torquebox OSCON Java 2011
Page 92: Torquebox OSCON Java 2011
Page 93: Torquebox OSCON Java 2011

BackStage

Dashboard to inspect and control Ruby components.

And a RESTful API.

Page 94: Torquebox OSCON Java 2011
Page 95: Torquebox OSCON Java 2011

StompBox

Easy Heroku-­esque git-­based deployments.

Page 96: Torquebox OSCON Java 2011
Page 97: Torquebox OSCON Java 2011

Oh yeah...It works on Windows.

Page 98: Torquebox OSCON Java 2011

Roadmap

1.1 Stable2.0 Development (based on JBoss AS7)??? -­ you tell us

Page 99: Torquebox OSCON Java 2011

Resources

•http://torquebox.org/

• http://github.com/torquebox

•#torquebox on FreeNode

•@torquebox

Page 100: Torquebox OSCON Java 2011
Page 101: Torquebox OSCON Java 2011

Thanks!Questions?

Target by Jasper Johns by nostri-­imago http://www.flickr.com/photos/nostri-­imago/3137422976/ CC BY 2.0WEB 2.0 HAS AN API by raster http://www.flickr.com/photos/raster/137506981/ CC BY-­NC-­SA 2.0Clock by Earls37a http://www.flickr.com/photos/indraw/4857101224/ CC BY-­SA 2.0Sink. by _Fidelio_ http://www.flickr.com/photos/photogaby/4129740673/ CC BY 2.0 Huge Queue 1 by danacea http://www.flickr.com/photos/danacea/2981199996/ CC BY-­NC 2.0Service as a Strategy Celebration at NCVS 2011 by Be The Change, Inc http://www.flickr.com/photos/bethechangeinc/5816393052/ CC BY-­NC 2.0Cash by ROSS HONG KONG http://www.flickr.com/photos/rossap/2716531616/ CC BY-­NC-­SA 2.0Injection by Dr Case http://www.flickr.com/photos/justin_case/3252846177/ CC BY-­NC 2.0IMG_1478 by akshaydavis http://www.flickr.com/photos/akshaydavis/166391476/ CC BY-­NC-­SA 2.0Rainforest by Chris.Gray http://www.flickr.com/photos/chriscgray/3946304802/ CC BY-­NC-­SA 2.0Community by niallkennedy http://www.flickr.com/photos/niallkennedy/40727794/ CC BY-­NC 2.0

Image attributions: