Bob McWhirter                                 Presented at DevNexus                                             22 March 2...
Bob McWhirter• Project  lead  of  TorqueBox• JBoss  Fellow• Founder  of  The  Codehaus• Founder  of  Drools• Been  with  R...
but its a team.
What is TorqueBox?The  mating  of  JRuby  to  JBoss AS.
Goals• Support  Ruby  web  frameworks • Rails • Sinatra • Rack• Go  beyond  the  web • Messaging • Jobs • Services
But......Java  already  supports  messaging,  jobs  and  services.
Thats right.
Why Ruby?• No  compilation• Low  ceremony• Highly  expressive• Lots  of  shiny  frameworks• Few  specifications  (more  fu...
Expressive                        anything.rbteams.    collect(&:members).    flatten.uniq.each  &:promote!
Uhh...                         com/foo/Anything.javaSet<Person>  people  =  new  HashSet<Person>();;for  (  Team  each  : ...
Why JRuby• Very  fast  runtime• Real  threads• Java  libraries• Java  tools• Healthy  community
Easy Install. Even on Windows$  wget  http://torquebox.org/torquebox-­dev.zip$  unzip  torquebox-­dev.zip$  export  TORQUE...
Easy Install. Even on Windows$ wget http://torquebox.org/torquebox-dev.zip$ unzip torquebox-dev.zip$  export  TORQUEBOX_HO...
Easy Install. Even on Windows$  wget  http://torquebox.org/torquebox-­dev.zip$  unzip  torquebox-­dev.zip$ export TORQUEBO...
Easy Install. Even on Windows$  wget  http://torquebox.org/torquebox-­dev.zip$  unzip  torquebox-­dev.zip Make  sure  the ...
The DetailsBuilds  upon  and  requires  JBoss  AS  6.x.    Tight  integration  with  the  JBoss  stack.
The CompetitionWarbler,  Trinidad,  Unicorn,  Thin,  Passenger......all  address  only  the  web  question.
WebRun  Ruby  web-­apps  within  the  context  of  the  Servlet  container.    Without compilation.
A rails applicationRAILS_ROOT/                         Filename    app/        models/            person.rb        views/ ...
Deploy!                     Filename$  rake  torquebox:deploy
But continue editingDeployment  does  not  create  archives  (by  default).Continue  live-­editing  of  running  app:  mod...
Non-surprising.Almost boring.
Web (Java Integration)                                  Filenameclass  SomeController    def  index        session[:passwo...
Web (Java Integration)                                                      Filenamepublic  class  SomeServlet  {    publi...
ClusteringRuby  applications  participate  fully  in  AS  clustering.Can  use  JBoss  mod_cluster.
mod_clusterA  reverse  proxy  implemented  as  an  Apache  module  with  JBoss  awareness.  Constantly  gathers  load  sta...
mod_cluster
mod_cluster• Dynamic  configuration• Server-­side  load  factor  calculation• Fine-­grained  web  app  lifecycle• AJP  (Ap...
Lets gobeyond the  web...
Scheduled Jobs
Jobs             app/jobs/newsletter_sender.rbclass  NewsletterSender      def run()        subscriptions  =  Subscription...
Jobs                        config/torquebox.ymljobs:    monthly_newsletter:        description:  first  of  month        ...
Messaging, Part 1   (async tasks)
Tasks                      app/tasks/email_task.rbclass  EmailTask  <  TorqueBox::Messaging::Task    def  welcome(payload)...
TasksEmailTask.async(:welcome,  payload  )
TasksCall  them  from  your  controllers,  models,  and  observers,  or  even  other  tasks.  Even  in  non-­Rails  apps!
Messaging, Part 2 (backgroundable)
Regular Class                   Filenameclass  Something    def  foo()    end    def  bar()    endend
Blocking invocations                              Filenamesomething  =  Something.newsomething.foosomething.bar
Backgroundable                                    Filenameclass  Something  include TorqueBox::Messaging::Backgroundable  ...
Non-blocking invocations                              Filenamesomething  =  Something.newsomething.background.foosomething...
Choices                                      Filenameclass  Something    include  TorqueBox::Messaging::Backgroundable  al...
Just do it right.                              Filenamesomething  =  Something.newsomething.foo
Messaging, Part 3    (low-level)
Destinationsconfig/torquebox.ymlqueues:    /queues/questions:    /queues/answers:        durable:  falsetopics:    /topics...
Processorsconfig/torquebox.ymlmessaging:  /topics/print: PrintHandler  /queues/popular:    - PopularHandler    - AdultObse...
Processorsapp/models/print_handler.rbinclude  TorqueBox::Messagingclass  PrintHandler  < MessageProcessor    def  initiali...
Queuesexampleinclude  TorqueBoxreq  =  Messaging::Queue.new  /queues/questionsres  =  Messaging::Queue.new  /queues/answer...
Queuesexampleinclude TorqueBoxreq = Messaging::Queue.new /queues/questionsres = Messaging::Queue.new /queues/answers  Thre...
Queuesexampleinclude  TorqueBoxreq  =  Messaging::Queue.new  /queues/questionsres  =  Messaging::Queue.new  /queues/answer...
Queuesexampleinclude  TorqueBoxreq  =  Messaging::Queue.new  /queues/questionsres  =  Messaging::Queue.new  /queues/answer...
Queues“on the fly”include  TorqueBoxqueue  =  Messaging::Queue.new  /queues/fooqueue.create    ...  queue.destroy
Topics• behavior  is  different,  but  interface  is    the  same.• all  subscribers  of  a  topic  see  each    message, ...
Servicesrun along, lil’ daemon
ServicesLong-­running,  non-­web  “daemons”  that  share  the  runtime  environment  and  deployment  lifecycle  of  your ...
Services• Represented  as  a  class  with    optional  initialize(Hash),      start()  and  stop()  methods,      which  s...
Servicesconfig/torquebox.ymlservices:    IrcBot:        server:  freenode.net        channel:  #torquebox        publish: ...
Servicesapp/{models,etc}/my_service.rbclass  MyService    def  initialize  opts={}        name  =  opts[:publish]        @...
Servicesapp/{models,etc}/my_service.rbclass  MyService    def initialize opts={}        name = opts[:publish]        @queu...
Servicesapp/{models,etc}/my_service.rbclass  MyService    def  initialize  opts={}        name  =  opts[:publish]        @...
Servicesapp/{models,etc}/my_service.rbclass  MyService    def  initialize  opts={}        name  =  opts[:publish]        @...
Servicesapp/{models,etc}/my_service.rbclass  MyService    def  run        until  @done            @queue.publish(Time.now)...
Servicesapp/{models,etc}/my_service.rbclass  MyService    def  run      until @done         @queue.publish(Time.now)      ...
Caching
Caching NoSQLIntegration  with  JBossInfinispan,  a  distributed/replicated  object  store.
Transparent InfinispanEasily  used  for  all  of  the  implicit  caching  within  Rails.Replace  in-­memory,  or  memcache...
Opaque Infinispan                                         Filenameinclude ActiveSupport::CachemyCache = TorqueBoxStore.new...
I N J E C T I O N    (we must go deeper)
Injection?Letting  the  container  figure  out  how  to  help  you  wire  up  complex  component  models.
akaInversion of ControlGuice, PicoContainer, JBoss Microcontainer
Java CDIpackage  com.mycorp;;           Filename@ApplicationScopedclass  Something  {    @Inject    private  Else  elsewis...
CDI Injectionclass  MyService    def  initialize  opts={}        @thing  =  cdi(com.mycorp.Something)    endend
CDI Injectionclass  MyService    def  initialize  opts={}        @thing  =  cdi(com.mycorp.Something)    endend
But theres more thanjust CDI you can inject.Theres also heroin,queues, topics andother things.But not really heroin.      ...
Destination Injectionclass  MyService    def  initialize  opts={}        @inbound    =  topic(  "/topics/questions"  )    ...
Destination Injectionclass  MyService    def  initialize  opts={}        @inbound    =  topic( "/topics/questions" )      ...
JNDI Injectionclass  MyService    def  initialize  opts={}        @factory  =  naming("java:comp/env/jdbc/myDS")    endend
JNDI Injectionclass  MyService    def  initialize  opts={}        @factory  =  naming("java:comp/env/jdbc/myDS")    endend
JBossMC Injectionclass  MyService    def  initialize  opts={}        @heroin  =  mc(  "SomeMCBean"  )    endend
JBossMC Injectionclass  MyService    def  initialize  opts={}        @heroin  =  mc( "SomeMCBean" )    endend
Why MC Beans?All  internal  plumbing  of  JBoss AS  is  stitched  together  using  MC.    Grab  the  WebServer,  the  Cach...
But thats not all!
BackStageDashboard  to  inspect  and  control  Ruby  components.And  a  RESTful  API.
StompBoxEasy  Heroku-­esque  git-­based  deployments.
StompBox
But how does it   perform?
BENchmarksReal-world Rail application:RedmineComparisons:TorqueBox,  Trinidad,  Passenger,  Unicorn,  Glassfish,  ThinRunt...
RoadmapMay - 1.0.0.FinalThen...    AS7    Authentication    Transactions    Drools/jBPM/etc    Mobicents
Resources•   http://torquebox.org/•   http://github.com/torquebox•   #torquebox  on  FreeNode•   @torquebox
Thanks, and dont forget to pick up  some stickers.
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus 2011.
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus 2011.
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus 2011.
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus 2011.
Upcoming SlideShare
Loading in...5
×

TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus 2011.

2,536

Published on

TorqueBox: The beauty of Ruby with the power of JBoss. Presented at DevNexus 2011 in Atlanta, Georgia.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,536
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
16
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus 2011.

  1. 1. Bob McWhirter Presented at DevNexus 22 March 2011Creative  Commons  BY-­SA  3.0
  2. 2. Bob McWhirter• Project  lead  of  TorqueBox• JBoss  Fellow• Founder  of  The  Codehaus• Founder  of  Drools• Been  with  Red  Hat  ~4  years
  3. 3. but its a team.
  4. 4. What is TorqueBox?The  mating  of  JRuby  to  JBoss AS.
  5. 5. Goals• Support  Ruby  web  frameworks • Rails • Sinatra • Rack• Go  beyond  the  web • Messaging • Jobs • Services
  6. 6. But......Java  already  supports  messaging,  jobs  and  services.
  7. 7. Thats right.
  8. 8. Why Ruby?• No  compilation• Low  ceremony• Highly  expressive• Lots  of  shiny  frameworks• Few  specifications  (more  fun!)• Meta
  9. 9. Expressive anything.rbteams.    collect(&:members).    flatten.uniq.each  &:promote!
  10. 10. Uhh... com/foo/Anything.javaSet<Person>  people  =  new  HashSet<Person>();;for  (  Team  each  :  teams  )  {    people.addAll(  each.getMembers()  );;}for  (  Person  each  :  people  )  {    each.promote();;}
  11. 11. Why JRuby• Very  fast  runtime• Real  threads• Java  libraries• Java  tools• Healthy  community
  12. 12. Easy Install. Even on Windows$  wget  http://torquebox.org/torquebox-­dev.zip$  unzip  torquebox-­dev.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
  13. 13. Easy Install. Even on Windows$ wget http://torquebox.org/torquebox-dev.zip$ unzip torquebox-dev.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
  14. 14. Easy Install. Even on Windows$  wget  http://torquebox.org/torquebox-­dev.zip$  unzip  torquebox-­dev.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
  15. 15. Easy Install. Even on Windows$  wget  http://torquebox.org/torquebox-­dev.zip$  unzip  torquebox-­dev.zip Make  sure  the  jruby   found  in  your  path  is  in   $JRUBY_HOME/bin.$  export  TORQUEBOX_HOME=$PWD/torquebox-­1*$  export  JBOSS_HOME=$TORQUEBOX_HOME/jboss$  export  JRUBY_HOME=$TORQUEBOX_HOME/jruby$ export PATH=$JRUBY_HOME/bin:$PATH
  16. 16. The DetailsBuilds  upon  and  requires  JBoss  AS  6.x.    Tight  integration  with  the  JBoss  stack.
  17. 17. The CompetitionWarbler,  Trinidad,  Unicorn,  Thin,  Passenger......all  address  only  the  web  question.
  18. 18. WebRun  Ruby  web-­apps  within  the  context  of  the  Servlet  container.    Without compilation.
  19. 19. A rails applicationRAILS_ROOT/ Filename    app/        models/            person.rb        views/            person/                index.html.haml                show.html.haml        controllers/            persons_controller.rb    lib/        my-­java-­components.jar    config/        database.yml        torquebox.yml
  20. 20. Deploy! Filename$  rake  torquebox:deploy
  21. 21. But continue editingDeployment  does  not  create  archives  (by  default).Continue  live-­editing  of  running  app:  models,views,  controllers...
  22. 22. Non-surprising.Almost boring.
  23. 23. Web (Java Integration) Filenameclass  SomeController    def  index        session[:password]  =  sw0rdfish    endend
  24. 24. Web (Java Integration) Filenamepublic  class  SomeServlet  {    public  void  doGet(HttpServletRequest  req,                                        HttpServletResponse  resp)      {        request.getSession().getValue("password");;    }}
  25. 25. ClusteringRuby  applications  participate  fully  in  AS  clustering.Can  use  JBoss  mod_cluster.
  26. 26. mod_clusterA  reverse  proxy  implemented  as  an  Apache  module  with  JBoss  awareness.  Constantly  gathers  load  statistics  and  deployment  availability  for  intelligent  request  distribution.
  27. 27. mod_cluster
  28. 28. mod_cluster• Dynamic  configuration• Server-­side  load  factor  calculation• Fine-­grained  web  app  lifecycle• AJP  (Apache  JServ  Protocol)  is   optional.  HTTP[S]  is  also  supported.
  29. 29. Lets gobeyond the web...
  30. 30. Scheduled Jobs
  31. 31. Jobs app/jobs/newsletter_sender.rbclass  NewsletterSender      def run()        subscriptions  =  Subscription.find(:all)        subscriptions.each  do  |e|            send_newsletter(  e  )        end    end  end
  32. 32. Jobs config/torquebox.ymljobs:    monthly_newsletter:        description:  first  of  month        job:  NewsletterSender        cron:  ‘0  0  0  1  *  ?’    sandbox:        job:  Sandbox        cron:  ‘*/5  *  *  *  *  ?’
  33. 33. Messaging, Part 1 (async tasks)
  34. 34. Tasks app/tasks/email_task.rbclass  EmailTask  <  TorqueBox::Messaging::Task    def  welcome(payload)        person  =  payload[:person]          person  ||=  Person.find_by_id(payload[:id])        if  person            #  send  the  email            person.welcomed  =  true            person.save!        end    endend
  35. 35. TasksEmailTask.async(:welcome,  payload  )
  36. 36. TasksCall  them  from  your  controllers,  models,  and  observers,  or  even  other  tasks.  Even  in  non-­Rails  apps!
  37. 37. Messaging, Part 2 (backgroundable)
  38. 38. Regular Class Filenameclass  Something    def  foo()    end    def  bar()    endend
  39. 39. Blocking invocations Filenamesomething  =  Something.newsomething.foosomething.bar
  40. 40. Backgroundable Filenameclass  Something include TorqueBox::Messaging::Backgroundable    def  foo()    end    def  bar()    endend
  41. 41. Non-blocking invocations Filenamesomething  =  Something.newsomething.background.foosomething.background.bar
  42. 42. Choices Filenameclass  Something    include  TorqueBox::Messaging::Backgroundable always_background :foo    def  foo()    end    def  bar()    endend
  43. 43. Just do it right. Filenamesomething  =  Something.newsomething.foo
  44. 44. Messaging, Part 3 (low-level)
  45. 45. Destinationsconfig/torquebox.ymlqueues:    /queues/questions:    /queues/answers:        durable:  falsetopics:    /topics/new_accounts    /topics/notifications
  46. 46. Processorsconfig/torquebox.ymlmessaging: /topics/print: PrintHandler /queues/popular: - PopularHandler - AdultObserver: filter: "age >= 18" concurrency: 5 /queues/students: PrintHandler: config: color: true
  47. 47. Processorsapp/models/print_handler.rbinclude  TorqueBox::Messagingclass  PrintHandler  < MessageProcessor    def  initialize(opts)        @color  =  opts[color]    end    def  on_message(body)        puts  "Processing  #{body}  of  #{message}"    endend
  48. 48. Queuesexampleinclude  TorqueBoxreq  =  Messaging::Queue.new  /queues/questionsres  =  Messaging::Queue.new  /queues/answers  Thread.new  do    req.publish  "What  time  is  it?"    puts  res.receive(  :timeout  =>  1000  )end  puts  req.receiveres.publish  Time.now
  49. 49. Queuesexampleinclude TorqueBoxreq = Messaging::Queue.new /queues/questionsres = Messaging::Queue.new /queues/answers  Thread.new  do    req.publish  "What  time  is  it?"    puts  res.receive(  :timeout  =>  1000  )end  puts  req.receiveres.publish  Time.now
  50. 50. Queuesexampleinclude  TorqueBoxreq  =  Messaging::Queue.new  /queues/questionsres  =  Messaging::Queue.new  /queues/answers  Thread.new do req.publish "What time is it?" puts res.receive( :timeout => 1000 )end  puts  req.receiveres.publish  Time.now
  51. 51. Queuesexampleinclude  TorqueBoxreq  =  Messaging::Queue.new  /queues/questionsres  =  Messaging::Queue.new  /queues/answers  Thread.new  do    req.publish  "What  time  is  it?"    puts  res.receive(  :timeout  =>  1000  )end  puts req.receiveres.publish Time.now
  52. 52. Queues“on the fly”include  TorqueBoxqueue  =  Messaging::Queue.new  /queues/fooqueue.create    ...  queue.destroy
  53. 53. 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
  54. 54. Servicesrun along, lil’ daemon
  55. 55. ServicesLong-­running,  non-­web  “daemons”  that  share  the  runtime  environment  and  deployment  lifecycle  of  your  app.
  56. 56. 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.
  57. 57. Servicesconfig/torquebox.ymlservices:    IrcBot:        server:  freenode.net        channel:  #torquebox        publish:  /topics/irc    MyMudServer:    SomeOtherService:
  58. 58. Servicesapp/{models,etc}/my_service.rbclass  MyService    def  initialize  opts={}        name  =  opts[:publish]        @queue  =  Messaging::Queue.new(name)    end    def  start          Thread.new  {  run  }      end    def  stop          @done  =  true    endend
  59. 59. Servicesapp/{models,etc}/my_service.rbclass  MyService def initialize opts={} name = opts[:publish] @queue = Messaging::Queue.new(name) end    def  start          Thread.new  {  run  }      end    def  stop          @done  =  true    endend
  60. 60. Servicesapp/{models,etc}/my_service.rbclass  MyService    def  initialize  opts={}        name  =  opts[:publish]        @queue  =  Messaging::Queue.new(name)    end def start Thread.new { run } end    def  stop          @done  =  true    endend
  61. 61. Servicesapp/{models,etc}/my_service.rbclass  MyService    def  initialize  opts={}        name  =  opts[:publish]        @queue  =  Messaging::Queue.new(name)    end    def  start          Thread.new  {  run  }      end def stop @done = true endend
  62. 62. Servicesapp/{models,etc}/my_service.rbclass  MyService    def  run        until  @done            @queue.publish(Time.now)            sleep(1)          end    endend
  63. 63. Servicesapp/{models,etc}/my_service.rbclass  MyService    def  run until @done @queue.publish(Time.now) sleep(1) end    endend
  64. 64. Caching
  65. 65. Caching NoSQLIntegration  with  JBossInfinispan,  a  distributed/replicated  object  store.
  66. 66. Transparent InfinispanEasily  used  for  all  of  the  implicit  caching  within  Rails.Replace  in-­memory,  or  memcached  caches.
  67. 67. Opaque Infinispan Filenameinclude ActiveSupport::CachemyCache = TorqueBoxStore.new(:name => MyCache, :mode => :replicated, :sync => true)
  68. 68. I N J E C T I O N (we must go deeper)
  69. 69. Injection?Letting  the  container  figure  out  how  to  help  you  wire  up  complex  component  models.
  70. 70. akaInversion of ControlGuice, PicoContainer, JBoss Microcontainer
  71. 71. Java CDIpackage  com.mycorp;; Filename@ApplicationScopedclass  Something  { @Inject    private  Else  elsewise;;}@ApplicationScopedclass  Else  {}
  72. 72. CDI Injectionclass  MyService    def  initialize  opts={}        @thing  =  cdi(com.mycorp.Something)    endend
  73. 73. CDI Injectionclass  MyService    def  initialize  opts={}        @thing  =  cdi(com.mycorp.Something)    endend
  74. 74. But theres more thanjust CDI you can inject.Theres also heroin,queues, topics andother things.But not really heroin. (Drugs are bad, mkay?)
  75. 75. Destination Injectionclass  MyService    def  initialize  opts={}        @inbound    =  topic(  "/topics/questions"  )        @outbound  =  queue(  "/queues/answers"  )    endend
  76. 76. Destination Injectionclass  MyService    def  initialize  opts={}        @inbound    =  topic( "/topics/questions" )        @outbound  =  queue( "/queues/answers" )    endend
  77. 77. JNDI Injectionclass  MyService    def  initialize  opts={}        @factory  =  naming("java:comp/env/jdbc/myDS")    endend
  78. 78. JNDI Injectionclass  MyService    def  initialize  opts={}        @factory  =  naming("java:comp/env/jdbc/myDS")    endend
  79. 79. JBossMC Injectionclass  MyService    def  initialize  opts={}        @heroin  =  mc(  "SomeMCBean"  )    endend
  80. 80. JBossMC Injectionclass  MyService    def  initialize  opts={}        @heroin  =  mc( "SomeMCBean" )    endend
  81. 81. Why MC Beans?All  internal  plumbing  of  JBoss AS  is  stitched  together  using  MC.    Grab  the  WebServer,  the  CacheManager,  whatevs.
  82. 82. But thats not all!
  83. 83. BackStageDashboard  to  inspect  and  control  Ruby  components.And  a  RESTful  API.
  84. 84. StompBoxEasy  Heroku-­esque  git-­based  deployments.
  85. 85. StompBox
  86. 86. But how does it perform?
  87. 87. BENchmarksReal-world Rail application:RedmineComparisons:TorqueBox,  Trinidad,  Passenger,  Unicorn,  Glassfish,  ThinRuntimes:JRuby,  MRI,  RubyEE
  88. 88. RoadmapMay - 1.0.0.FinalThen...    AS7    Authentication    Transactions    Drools/jBPM/etc    Mobicents
  89. 89. Resources• http://torquebox.org/• http://github.com/torquebox• #torquebox  on  FreeNode• @torquebox
  90. 90. Thanks, and dont forget to pick up some stickers.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×