TorqueBox - Ruby Hoedown 2011

  • 1,593 views
Uploaded on

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

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

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,593
On Slideshare
0
From Embeds
0
Number of Embeds
4

Actions

Shares
Downloads
12
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \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

Transcript

  • 1. A True Application Server for Ruby Lance Ball Ruby HoedownCreative Commons BY-SA 3.0 August 2011
  • 2. Lance Ball• TorqueBox Core Developer• Red Hat Senior Engineer• Perl -> C++ -> Java -> Ruby• @lanceball
  • 3. project:odd
  • 4. What is TorqueBox?Ruby Application Server Built on JBoss & JRubyThe Power of JBoss with the Expressiveness of Ruby
  • 5. JBoss AS7TorqueBox is tightlyintegrated with JBoss.Extends JBoss AS7 toenable a JRuby runtime.
  • 6. JRuby•Very fast runtime•Real threads•Java libraries•Java tools•Healthy community
  • 7. Ruby App Sinatra Rails Rack Passenger/Thin Apache/Nginx
  • 8. Ruby App Sinatra Rails Rack Tasks Passenger/Thin Resque/DelayedJob Apache/Nginx
  • 9. Ruby App Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/DelayedJob Apache/Nginx crond
  • 10. Ruby App Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/DelayedJob Apache/Nginx crond Daemons god/monit
  • 11. Goals
  • 12. Goals No XML, No Java (unless youre into that sort of thing)
  • 13. Goals•Support Ruby web frameworks •Rails •Sinatra •Rack
  • 14. GoalsThe Obvious & Necessary • Rails • Sinatra • RackBut do more! • Messaging • Jobs • Services • Plus Even More!
  • 15. TorqueBox ASSinatra Rails Rack Tasks Procs Jobs Daemons Web Messaging Scheduling Services JBoss AS Clustering Load Balancing HA
  • 16. WebRuby web apps in JBossRack, Rails, Sinatra
  • 17. Webconfig/torquebox.ymlapplication: root: /path/to/myapp env: productionweb: context: / host: www.myapp.comenvironment: MAIL_HOST: mail.myapp.com
  • 18. Live Editing Live updates for Rails apps models, views, controllers...
  • 19. What Else?
  • 20. ClusteringRuby apps participate in ASclustering with mod_cluster
  • 21. 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.
  • 22. CachingInfinispanA distributed, replicatedobject store.
  • 23. Transparent Infinispan Used for all implicit caching in Rails. Replaces in-memory or memcached caches.
  • 24. Cachingconfig/application.rbmodule YourApp  class Application < Rails::Application    config.cache_store = :torque_box_store endend
  • 25. Cachingmy_app.rbrequire sinatrarequire torqueboxclass MyApp < Sinatra::Base  use TorqueBox::Session::ServletStore  get / do    session[:message] = Hello World!    haml :index  endend
  • 26. Opaque Infinispansome_file.rbinclude ActiveSupport::CachemyCache = TorqueBoxStore.new(:name => MyCache, :mode => :replicated)
  • 27. Jobsapp/jobs/newsletter_sender.rbclass NewsletterSender   def run()    subscriptions = Subscription.find(:all)    subscriptions.each do |e|      send_newsletter(e)    end  end end
  • 28. 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
  • 29. Regular Classclass User  def send_welcome_email    # do something that takes a while  endend
  • 30. Blocking invocationsuser = User.newuser.send_welcome_email
  • 31. Backgroundableclass User  include TorqueBox::Messaging::Backgroundable  def send_welcome_email    # do something that takes a while  endend
  • 32. Explicitly Non-blockinguser = User.newuser.background.send_welcome_email
  • 33. Choicesclass User  include TorqueBox::Messaging::Backgroundable  always_background :send_welcome_email  def send_welcome_email    # do something that takes a while  endend
  • 34. Implicitly Non-blockinguser = User.newuser.send_welcome_email
  • 35. See The Futureuser = User.newfuture = user.send_welcome_email
  • 36. See The Futurefuture.started?future.complete?future.error?future.result
  • 37. See The Futureclass User  def send_welcome_email    while( !@finished )      ...      count += 1      future.status = count      ...    end  endend
  • 38. See The Future# on the client sidefuture.status_changed?future.status # => 42
  • 39. Messaging•JMS behind the scenes•implementation HornetQ is the JBoss JMS
  • 40. Destinationsconfig/torquebox.ymlqueues: /queues/questions: /queues/answers: durable: false
  • 41. 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 )
  • 42. 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 )
  • 43. 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 )
  • 44. 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 )
  • 45. Queues“on the fly”include TorqueBox::Messagingqueue = Queue.new(/queues/foo)queue.create# ... queue.destroy
  • 46. Processorsconfig/torquebox.ymlmessaging: /queues/receipts: PrintHandler: concurrency: 5 config: printer: the_little_one
  • 47. 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
  • 48. 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
  • 49. ServicesLong-running, non-web“daemons” that sharethe runtime environmentand deployment lifecycleof your app.
  • 50. 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.
  • 51. Servicesconfig/torquebox.ymlservices: TimeMachine: queue: /queue/morris_day IrcBot: server: freenode.net channel: #torquebox publish: /topics/irc singleton: true
  • 52. 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
  • 53. 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
  • 54. 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
  • 55. 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
  • 56. 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
  • 57. Resource InjectionLetting the containerfigure out how to helpyou wire up complexcomponent models.
  • 58. akaInversion of Control
  • 59. CDI Resourcesclass MyService  include TorqueBox::Injectors  def initialize opts={}    @thing = inject(com.mycorp.Something)  endend
  • 60. But you can inject lotsof things - not just CDIobjects.
  • 61. Destination Injectionclass MyService  include TorqueBox::Injectors  def initialize( opts={} )    @inbound = inject("/queues/questions")    @outbound = inject("/queues/answers")  endend
  • 62. JNDI Injectionclass MyService  include TorqueBox::Injectors  def initialize opts={}    @factory = inject("java:comp/env/jdbc/myDS")  endend
  • 63. JBossMC Injectionclass MyService  include TorqueBox::Injectors  def initialize opts={}    @pinto = inject("SomeMCBean")  endend
  • 64. Why MC Beans?All internal plumbing ofJBoss AS is stitchedtogether using MC beans.Grab the WebServer, theCacheManager, whatevs.
  • 65. Web Sockets•Uses STOMP (protocol)•And Stilts(framework)•Provides Stomplet “Controllers”•Simple JMS Bridging
  • 66. Stomplet API configure( config ) on_subscribe( subscriber ) on_unsubscribe( subscriber ) on_message( message, session )
  • 67. 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
  • 68. 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
  • 69. 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
  • 70. 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
  • 71. JmsStomplet APIsubscribe_to( subscriber, destination )send_to( destination, message, headers )
  • 72. 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
  • 73. 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
  • 74. Web Socketsconfig/torquebox.yml stomp: stomplets: broadcast.stomplet: route: /sockets/broadcast class: BroadcastStomplet jms.stomplet: route: /sockets/irc class: IrcStomplet config: destination: /queues/irc
  • 75. 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>") })   }) })
  • 76. BENchmarksReal-world Rail application:RedmineComparisons:TorqueBox, Trinidad, Glassfish,Passenger, Unicorn, ThinRuntimes:JRuby, MRI, RubyEE
  • 77. BackStageDashboard to inspectand control Rubycomponents.And a RESTful API.
  • 78. StompBoxEasy Heroku-esquegit-based deployments.
  • 79. dm-infinispan-adapter•DataMapper on Infinispan•Replicated NoSQL store
  • 80. 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
  • 81. Oh yeah...It works on Windows.
  • 82. Roadmap1.1.1 Stable2.0 In Development??? - you tell us
  • 83. Resources• http://torquebox.org/• http://github.com/ torquebox• #torquebox on FreeNode• @torquebox
  • 84. 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