• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
TorqueBox - Ruby Hoedown 2011
 

TorqueBox - Ruby Hoedown 2011

on

  • 1,813 views

My TorqueBox presentation at the 2011 Ruby Hoedown in Nashville, TN.

My TorqueBox presentation at the 2011 Ruby Hoedown in Nashville, TN.

Statistics

Views

Total Views
1,813
Views on SlideShare
1,030
Embed Views
783

Actions

Likes
1
Downloads
11
Comments
0

12 Embeds 783

http://torquebox.org 655
http://localhost 58
http://subjot.com 30
http://staging.torquebox.org 27
http://www.hanrss.com 3
https://twitter.com 2
http://torquebox.dev 2
https://si0.twimg.com 2
http://twitter.com 1
http://a0.twimg.com 1
https://abs.twimg.com 1
http://planet.jboss.org 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • What? JBoss? Isn’t that Java?\n
  • to provide all we do, we have to be tightly integrated.\nwhich means no glassfish/websphere/whatever\n
  • First class ruby\n\n
  • java developers know what an app server is\n
  • \n
  • \n
  • redeploy\n
  • Target Audience for TorqueBox\n
  • \n
  • We write Java so you don’t have to\n
  • Parity with existing ruby options.\n
  • Expose what an AS can provide.\n
  • TorqueBox brings that all together\norange is ruby, red is java\n
  • components - start with Web - a series of tubes\n
  • in development mode\n
  • \n
  • Where supported. Live editing isn’t enabled in Sinatra by default anymore\n
  • from a rubyists perspective\nminimum requirement for ruby development. It's expected.\n
  • \n
  • \n
  • As server nodes join and leave the cluster, the balancer (mod_cluster) is aware of these changes.\n
  • anyone using infinispan?\n\n
  • we make it easy to use from rails, or anything using the ActiveSupport library\n
  • \n
  • \n
  • we provide TorqueBoxStore, which has the same api as the memcached store\n
  • Scheduled Jobs\n
  • Only a run() method is required\n
  • Jobs run on every node unless singleton: true\n\nSeconds - Minutes - Hours - Day of Month - Month - Day of Week - Year\n\n\n
  • Asynchronous tasks\n
  • \n
  • \n
  • \n
  • returns immediately\nguts execute on a separate thread\n
  • \n
  • returns immediately\nguts execute on a separate thread\n
  • allows you to monitor the async execution\n
  • \n
  • \n
  • uses messaging underneath (queues)\n
  • Messaging\nwe expose those messaging abstractions\n
  • \n
  • created at deploy time\n
  • shows publish and receive\n\n
  • \n
  • \n
  • \n
  • be sure to destroy\n
  • \n
  • Ruby messages are Marshaled and Base64-encoded\n
  • same semantics\n
  • Services\n
  • demons!\n
  • \n
  • !!!singleton!\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Resource Injection\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • How does it perform?\nIs it the car or the truck?\ncomparing against other ruby stacks is easy \nbut comparing java to ruby it's hard to get anything meaningful\n
  • 10 minute warmup, load increasing every 10 minutes thereafter\n
  • \n
  • Good blog post on torquebox.org\n
  • The TorqueBox Ecosystem\n
  • deploy to TB\ninspect & manage queues, message processors, ruby runtimes, services, jobs\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • which is no surprise to java devs, but often is to rubyists\n
  • we have a few other things, but you tell us\n
  • OSS (LGPL) - letter, but not modern intent\nactive in mailing lists and irc\nDocumentation with most features on push\ndistributed team - irc tech discussions\nwe offer the process as ONE example, and welcome feedback!\nhowever you do it, focus on your community!\n
  • \n
  • \n

TorqueBox - Ruby Hoedown 2011 TorqueBox - Ruby Hoedown 2011 Presentation Transcript

  • A True Application Server for Ruby Lance Ball Ruby HoedownCreative Commons BY-SA 3.0 August 2011
  • Lance Ball• TorqueBox Core Developer• Red Hat Senior Engineer• Perl -> C++ -> Java -> Ruby• @lanceball
  • project:odd
  • What is TorqueBox?Ruby Application Server Built on JBoss & JRubyThe Power of JBoss with the Expressiveness of Ruby
  • JBoss AS7TorqueBox is tightlyintegrated with JBoss.Extends JBoss AS7 toenable a JRuby runtime.
  • JRuby•Very fast runtime•Real threads•Java libraries•Java tools•Healthy community
  • Ruby App Sinatra Rails Rack Passenger/Thin Apache/Nginx
  • Ruby App Sinatra Rails Rack Tasks Passenger/Thin Resque/DelayedJob Apache/Nginx
  • Ruby App Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/DelayedJob Apache/Nginx crond
  • Ruby App Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/DelayedJob Apache/Nginx crond Daemons god/monit
  • Goals
  • Goals No XML, No Java (unless youre into that sort of thing)
  • Goals•Support Ruby web frameworks •Rails •Sinatra •Rack
  • GoalsThe Obvious & Necessary • Rails • Sinatra • RackBut do more! • Messaging • Jobs • Services • Plus Even More!
  • TorqueBox ASSinatra Rails Rack Tasks Procs Jobs Daemons Web Messaging Scheduling Services JBoss AS Clustering Load Balancing HA
  • WebRuby web apps in JBossRack, Rails, Sinatra
  • Webconfig/torquebox.ymlapplication: root: /path/to/myapp env: productionweb: context: / host: www.myapp.comenvironment: MAIL_HOST: mail.myapp.com
  • Live Editing Live updates for Rails apps models, views, controllers...
  • What Else?
  • ClusteringRuby apps participate in ASclustering with mod_cluster
  • Clustering: mod_cluster A reverse proxy implemented as an Apache module with JBoss awareness. Constantly gathers load statistics and deployment availability for intelligent request distribution.
  • CachingInfinispanA distributed, replicatedobject store.
  • Transparent Infinispan Used for all implicit caching in Rails. Replaces in-memory or memcached caches.
  • Cachingconfig/application.rbmodule YourApp  class Application < Rails::Application    config.cache_store = :torque_box_store endend
  • Cachingmy_app.rbrequire sinatrarequire torqueboxclass MyApp < Sinatra::Base  use TorqueBox::Session::ServletStore  get / do    session[:message] = Hello World!    haml :index  endend
  • Opaque Infinispansome_file.rbinclude ActiveSupport::CachemyCache = TorqueBoxStore.new(:name => MyCache, :mode => :replicated)
  • Jobsapp/jobs/newsletter_sender.rbclass NewsletterSender   def run()    subscriptions = Subscription.find(:all)    subscriptions.each do |e|      send_newsletter(e)    end  end end
  • Jobsconfig/torquebox.ymljobs: 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
  • Regular Classclass User  def send_welcome_email    # do something that takes a while  endend
  • Blocking invocationsuser = User.newuser.send_welcome_email
  • Backgroundableclass User  include TorqueBox::Messaging::Backgroundable  def send_welcome_email    # do something that takes a while  endend
  • Explicitly Non-blockinguser = User.newuser.background.send_welcome_email
  • Choicesclass User  include TorqueBox::Messaging::Backgroundable  always_background :send_welcome_email  def send_welcome_email    # do something that takes a while  endend
  • Implicitly Non-blockinguser = User.newuser.send_welcome_email
  • See The Futureuser = User.newfuture = user.send_welcome_email
  • See The Futurefuture.started?future.complete?future.error?future.result
  • See The Futureclass User  def send_welcome_email    while( !@finished )      ...      count += 1      future.status = count      ...    end  endend
  • See The Future# on the client sidefuture.status_changed?future.status # => 42
  • Messaging•JMS behind the scenes•implementation HornetQ is the JBoss JMS
  • Destinationsconfig/torquebox.ymlqueues: /queues/questions: /queues/answers: durable: false
  • Queuescontrived examplequestions = 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 )
  • Queuescontrived examplequestions = 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 )
  • Queuescontrived examplequestions = 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 )
  • Queuescontrived examplequestions = 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 )
  • Queues“on the fly”include TorqueBox::Messagingqueue = Queue.new(/queues/foo)queue.create# ... queue.destroy
  • Processorsconfig/torquebox.ymlmessaging: /queues/receipts: PrintHandler: concurrency: 5 config: printer: the_little_one
  • Processorsapp/models/print_handler.rbinclude TorqueBox::Messagingclass PrintHandler < MessageProcessor  def initialize(opts)    @printer = opts[printer] || default  end  def on_message(body)    puts "Processing #{body} of #{message}"  endend
  • Topics•interface is different, but behavior is the same.•each message, of a only one all subscribers but topic see subscriber will see any message from a queue• use TorqueBox::Messaging::Topic
  • ServicesLong-running, non-web“daemons” that sharethe runtime environmentand deployment lifecycleof your app.
  • Services•methods, which shouldstop() A class with start() and each return quickly. Optionally provide initialize(Hash).•running loop startthread and Typically will in a a long- respond to external events.
  • Servicesconfig/torquebox.ymlservices: TimeMachine: queue: /queue/morris_day IrcBot: server: freenode.net channel: #torquebox publish: /topics/irc singleton: true
  • Servicesapp/services/time_machine.rbclass TimeMachine  def initialize(opts)    @queue = Queue.new(opts[queue])  end  def start    Thread.new { run }  end  def stop    @done = true  end   def run    # ...  endend
  • Servicesapp/services/time_machine.rbclass TimeMachine  def initialize(opts)    @queue = Queue.new(opts[queue])  end  def start    Thread.new { run }  end  def stop    @done = true  end   def run    # ...  endend
  • Servicesapp/services/time_machine.rbclass TimeMachine  def initialize(opts)    @queue = Queue.new(opts[queue])  end  def start    Thread.new { run }  end  def stop    @done = true  end   def run    # ...  endend
  • Servicesapp/services/time_machine.rbclass TimeMachine  def initialize(opts)    @queue = Queue.new(opts[queue])  end  def start    Thread.new { run }  end  def stop    @done = true  end   def run    # ...  endend
  • Services app/services/time_machine.rbclass TimeMachine  def initialize(opts)    @queue = Queue.new(opts[queue])  end  def start    Thread.new { run }  end  def stop    @done = true  end   def run    until @done      @queue.publish(Time.now)      sleep(1)    end  endend
  • Resource InjectionLetting the containerfigure out how to helpyou wire up complexcomponent models.
  • akaInversion of Control
  • CDI Resourcesclass MyService  include TorqueBox::Injectors  def initialize opts={}    @thing = inject(com.mycorp.Something)  endend
  • But you can inject lotsof things - not just CDIobjects.
  • Destination Injectionclass MyService  include TorqueBox::Injectors  def initialize( opts={} )    @inbound = inject("/queues/questions")    @outbound = inject("/queues/answers")  endend
  • JNDI Injectionclass MyService  include TorqueBox::Injectors  def initialize opts={}    @factory = inject("java:comp/env/jdbc/myDS")  endend
  • JBossMC Injectionclass MyService  include TorqueBox::Injectors  def initialize opts={}    @pinto = inject("SomeMCBean")  endend
  • Why MC Beans?All internal plumbing ofJBoss AS is stitchedtogether using MC beans.Grab the WebServer, theCacheManager, whatevs.
  • Web Sockets•Uses STOMP (protocol)•And Stilts(framework)•Provides Stomplet “Controllers”•Simple JMS Bridging
  • Stomplet API configure( config ) on_subscribe( subscriber ) on_unsubscribe( subscriber ) on_message( message, session )
  • Web Socketsapp/stomplets/broadcast_stomplet.rb require torquebox-stomp class BroadcastStomplet   def on_subscribe(subscriber)     @subscribers << subscriber   end     def on_unsubscribe(subscriber)     @subscribers.delete( subscriber )   end   def on_message(stomp_message, session)     @subscribers.each do |subscriber|       subscriber.send( stomp_message )     end   end end
  • Web Socketsapp/stomplets/broadcast_stomplet.rb require torquebox-stomp class BroadcastStomplet   def on_subscribe(subscriber)     @subscribers << subscriber   end     def on_unsubscribe(subscriber)     @subscribers.delete( subscriber )   end   def on_message(stomp_message, session)     @subscribers.each do |subscriber|       subscriber.send( stomp_message )     end   end end
  • Web Socketsapp/stomplets/broadcast_stomplet.rb require torquebox-stomp class BroadcastStomplet   def on_subscribe(subscriber)     @subscribers << subscriber   end     def on_unsubscribe(subscriber)     @subscribers.delete( subscriber )   end   def on_message(stomp_message, session)     @subscribers.each do |subscriber|       subscriber.send( stomp_message )     end   end end
  • Web Socketsapp/stomplets/broadcast_stomplet.rb require torquebox-stomp class BroadcastStomplet   def on_subscribe(subscriber)     @subscribers << subscriber   end     def on_unsubscribe(subscriber)     @subscribers.delete( subscriber )   end   def on_message(stomp_message, session)     @subscribers.each do |subscriber|       subscriber.send( stomp_message )     end   end end
  • JmsStomplet APIsubscribe_to( subscriber, destination )send_to( destination, message, headers )
  • JMS Stompletapp/stomplets/irc_stomplet.rb class IrcStomplet < TorqueBox::Stomp::JmsStomplet   include TorqueBox::Messaging   def configure(config)     @destination = Queue.new( config[destination] )   end   def on_subscribe(subscriber) # subscribe the client to a JMS message queue     subscribe_to( subscriber, @destination ) # send a message to the queue     send_to( @destination, "TorqueBoxBot in da house", :sender => :system, :timestamp => Time.now.ctime )   end end
  • IRC Bot Serviceapp/services/irc_bot_service.rb class IrcBotService   include TorqueBox::Messaging      def start     @bot = configure_bot     @bot_thread = Thread.new { @bot.connect }   end   def configure_bot # ...     # Log all channel messages to the queue     bot.on :channel do |event_data|       @destination.publish( event_data[:message], :properties => {:sender=>event_data[:nick], :timestamp=>Time.now.ctime} )     end     bot   end end
  • Web Socketsconfig/torquebox.yml stomp: stomplets: broadcast.stomplet: route: /sockets/broadcast class: BroadcastStomplet jms.stomplet: route: /sockets/irc class: IrcStomplet config: destination: /queues/irc
  • Web Socketsjavascripts/application.js $( function() {   client = Stomp.client( "ws://localhost:8675/" )   client.connect( null, null, function() {     $(window).unload(function() { client.disconnect() });          client.subscribe( /sockets/bridge, function( message ) {    $("#messages").append("<li>" + message.body + "</li>") })   }) })
  • BENchmarksReal-world Rail application:RedmineComparisons:TorqueBox, Trinidad, Glassfish,Passenger, Unicorn, ThinRuntimes:JRuby, MRI, RubyEE
  • BackStageDashboard to inspectand control Rubycomponents.And a RESTful API.
  • StompBoxEasy Heroku-esquegit-based deployments.
  • dm-infinispan-adapter•DataMapper on Infinispan•Replicated NoSQL store
  • Installation & Deployment$ gem install torquebox-server --pre --source http://torquebox.org/2x/builds/LATEST/gem-repo/$ torquebox Tasks: torquebox deploy ROOT # Deploy an application to TorqueBox torquebox undeploy ROOT # Undeploy an application from TorqueBox torquebox run # Run TorqueBox torquebox cli # Run the JBoss AS7 CLI torquebox help [TASK] # Describe available tasks or one specific task
  • Oh yeah...It works on Windows.
  • Roadmap1.1.1 Stable2.0 In Development??? - you tell us
  • Resources• http://torquebox.org/• http://github.com/ torquebox• #torquebox on FreeNode• @torquebox
  • Thanks! Questions?Image attributions:Soccer Youth Goal Keeper by Torsten Bolten http://en.wikipedia.org/wiki/File:Soccer_Youth_Goal_Keeper.jpgSeries of tubes by ritingon http://www.flickr.com/photos/ritingonthewall/2579076693/Yawning is danger! by dj badly http://www.flickr.com/photos/djbadly/2052098189/EuroFoo Schedule by silent-penguin http://www.flickr.com/photos/silent-penguin/232394/Sink. by _Fidelio_ http://www.flickr.com/photos/photogaby/4129740673/ CC BY 2.0Telegraph Practice Set from Popular Science, Feb 1947 http://books.google.com/books?id=uyUDAAAAMBAJ&lpg=PA65&pg=PT83#v=onepage&q&f=falseService 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