Your SlideShare is downloading. ×
0
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Torquebox OSCON Java 2011

2,862

Published on

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

  • Be the first to like this

No Downloads
Views
Total Views
2,862
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
22
Comments
0
Likes
0
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

Transcript

  • 1. The Beauty of Ruby with the Power of Java Toby Crawley OSCON JavaCreative  Commons  BY-­SA  3.0 July 2011
  • 2. Toby  Crawley!• @tcrawley• TorqueBox  Core  Developer• Red  Hat  Senior  Engineer  
  • 3. but  its  a  team.
  • 4. What  is  TorqueBox? The  mating  of  JRuby  to   JBoss  AS.
  • 5. Application  Server? Sinatra Rails Rack Passenger/Thin Apache/Nginx
  • 6. Application  Server? Sinatra Rails Rack Tasks Passenger/Thin Resque/ DelayedJob Apache/Nginx
  • 7. Application  Server? Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/ DelayedJob Apache/Nginx crond
  • 8. Application  Server? Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/ DelayedJob Apache/Nginx crond Daemons god/monit
  • 9. TorqueBox  ASSinatra Rails Rack Tasks Procs Jobs Daemons Web Messaging Scheduling Services JBoss AS Clustering Load Balancing HA
  • 10. Goals• Support  Ruby  web  frameworks • Rails • Sinatra • Rack
  • 11. Goals• Support  Ruby  web  frameworks • Rails • Sinatra • Rack• Go  beyond  the  web • Messaging • Jobs • Services
  • 12. Goals No  XML,  No  Java(unless  youre  into  that  sort  of  thing)
  • 13. Why  Ruby?• No  compilation• Highly  expressive• Lots  of  shiny  frameworks• Few  specifications  (more  fun!)• Meta-­programming
  • 14. Expressivecom/foo/Anything.javaSet<Person>  people  =  new  HashSet<Person>();;for  (  Team  each  :  teams  )  {    people.addAll(  each.getMembers()  );;}for  (  Person  each  :  people  )  {    each.promote();;}
  • 15. Expressiveanything.rbteams.collect(&:members).  flatten.uniq.each(&:promote)
  • 16. Expressiveanything.rball_members  =          teams.collect(&:members)all_members.flatten!.uniq!all_members.each(&:promote)
  • 17. Why  JRuby?
  • 18. Why  JRuby?system  =  Java::java.lang.Systemsystem.properties.each  do  |k,v|    system.properties[k]  =  v.upcaseend
  • 19. Why  JRuby?• Very  fast  runtime• Real  threads• Java  libraries• Java  tools• Healthy  community
  • 20. TorqueBox  Details Builds  upon  and  requires   JBoss  AS  6.x.     Tight  integration  with  the   JBoss  stack.
  • 21. 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
  • 22. 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
  • 23. 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
  • 24. 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
  • 25. Easy  Install(download  1.1  from  torquebox.org)$  unzip  torquebox-­dist-­1.0.0.CR1-­bin.zip Make  sure  the  jruby   found  in  your  path  is  in  $  export  TORQUEBOX_HOME=$PWD/torquebox-­1* $JRUBY_HOME/bin.$  export  JBOSS_HOME=$TORQUEBOX_HOME/jboss$  export  JRUBY_HOME=$TORQUEBOX_HOME/jruby$  export  PATH=$JRUBY_HOME/bin:$PATH
  • 26. Easy  Install(download  1.1  from  torquebox.org)$  unzip  torquebox-­dist-­1.0.0.CR1-­bin.zip Make  sure  the  jruby   found  in  your  path  is  in  $  export  TORQUEBOX_HOME=$PWD/torquebox-­1* $JRUBY_HOME/bin.$  export  JBOSS_HOME=$TORQUEBOX_HOME/jboss$  export  JRUBY_HOME=$TORQUEBOX_HOME/jruby$  export  PATH=$JRUBY_HOME/bin:$PATH
  • 27. Deploymentrake  torquebox:run        Run  TorqueBox  serverrake  torquebox:deploy[context_path]        Deploy  the  app  in  the  current  directoryrake  torquebox:undeploy        Undeploy  the  app  in  the  current  directory
  • 28. DeploymentThe  torquebox:deploy  task  creates:$TORQUEBOX_HOME/apps/my-­app.yml
  • 29. WebRun  Ruby  web-­apps  within  the  context  of  the  Servlet  container.    Without  compilation.
  • 30. But  continue  editing Continue  live-­editing  of  running   app:   models,views,  controllers...
  • 31. Non-­surprising.  Almost  boring.
  • 32. Web  (Session  Integration)class  SomeController    def  index        session[:password]  =  sw0rdfish    endend
  • 33. Web  (Session  Integration)public  class  SomeServlet  {    public  void  doGet(HttpServletRequest  request,                                        HttpServletResponse  resp)  {        request.getSession().getValue("password");;        }}
  • 34. ClusteringRuby  applications  participate  fully  in  AS  clustering.Can  use  JBoss  mod_cluster.
  • 35. mod_clusterA  reverse  proxy  implemented  as  an  Apache  module  with  JBoss  awareness.  Constantly  gathers  load  statistics  and  deployment  availability  for  intelligent  request  distribution.
  • 36. Lets  go  beyond  the   web...
  • 37. Jobsapp/jobs/newsletter_sender.rbclass  NewsletterSender      def  run()        subscriptions  =  Subscription.find(:all)        subscriptions.each  do  |e|            send_newsletter(e)        end    end  end
  • 38. 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
  • 39. Regular  Classclass  Something    def  foo    end    def  bar    endend
  • 40. Blocking  invocationssomething  =  Something.newsomething.foosomething.bar
  • 41. Backgroundableclass  Something    include  TorqueBox::Messaging::Backgroundable    def  foo    end    def  bar    endend
  • 42. Explicitly  Non-­blocking  something  =  Something.newsomething.background.foosomething.background.bar
  • 43. Choicesclass  Something    include  TorqueBox::Messaging::Backgroundable    always_background  :foo    def  foo    end    def  bar    endend
  • 44. Implicitly  Non-­blocking  something  =  Something.newsomething.foo
  • 45. See  The  Futuresomething  =  Something.newfuture  =  something.foo
  • 46. See  The  Futurefuture.started?future.complete?future.error?future.result
  • 47. See  The  Futureclass  Something    def  foo        ...        count  +=  1        future.status  =  count        ...    endend  
  • 48. See  The  Future#  on  the  client  sidefuture.status_changed?future.status  #  =>  42
  • 49. Messaging• JMS  behind  the  scenes• HornetQ  is  the  JBoss  JMS   implementation
  • 50. Destinationsconfig/torquebox.ymlqueues:    /queues/questions:    /queues/answers:        durable:  falsetopics:    /topics/new_accounts    /topics/notifications
  • 51. 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
  • 52. Processorsconfig/torquebox.ymlmessaging: /topics/orders: - PrintHandler - ShoutHandler /queues/receipts: PrintHandler: concurrency: 5 config: printer: the_little_one
  • 53. 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  )
  • 54. 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  )
  • 55. 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  )
  • 56. 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  )
  • 57. Queues“on  the  fly”include  TorqueBox::Messagingqueue  =  Queue.new(/queues/foo)queue.create    ...  queue.destroy
  • 58. 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
  • 59. ServicesLong-­running,  non-­web  “daemons”  that  share  the  runtime  environment  and  deployment  lifecycle  of  your  app.
  • 60. 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.
  • 61. Servicesconfig/torquebox.ymlservices:    TimeMachine:        queue:  /queue/morris_day    IrcBot:        server:  freenode.net        channel:  #torquebox        publish:  /topics/irc        singleton:  true
  • 62. 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      endend
  • 63. 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    endend
  • 64. 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    endend
  • 65. 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    endend
  • 66. Servicesapp/services/time_machine.rbclass  TimeMachine    def  run          until  @done            @queue.publish(Time.now)            sleep(1)          end    endend
  • 67. Servicesapp/services/time_machine.rbclass  TimeMachine    def  run          until  @done            @queue.publish(Time.now)            sleep(1)          end    endend
  • 68. CachingIntegration  with  JBoss  Infinispan,  a  distributed/replicated  object  store.
  • 69. Transparent  Infinispan Easily  used  for  all  of  the   implicit  caching  within   Rails. Replace  in-­memory,  or   memcached  caches.
  • 70. Opaque  Infinispaninclude ActiveSupport::CachemyCache = TorqueBoxStore.new(:name => MyCache, :mode => :replicated, :sync => true)
  • 71. Injection? Letting  the  container  figure   out  how  to  help  you  wire   up  complex  component   models.
  • 72. aka Inversion  of  ControlGuice, PicoContainer, JBoss Microcontainer
  • 73. Java  CDIpackage  com.mycorp;;@ApplicationScopedclass  Something  {    @Inject    private  SomethingElse  elsewise;;}@ApplicationScopedclass  SomethingElse  {}
  • 74. CDI  Injectionclass  MyService    include  TorqueBox::Injectors    def  initialize  opts={}        @thing  =  inject(com.mycorp.Something)    endend
  • 75. But  theres  more  than  just  CDI  you  can  inject.    Theres  also  queues,  topics,  heroin  and  other  things.    
  • 76. Destination  Injectionclass  MyService    include  TorqueBox::Injectors    def  initialize  opts={}        @inbound    =  inject("/topics/questions")        @outbound  =  inject("/queues/answers")    endend
  • 77. JNDI  Injectionclass  MyService    include  TorqueBox::Injectors    def  initialize  opts={}        @factory  =  inject("java:comp/env/jdbc/myDS")    endend
  • 78. JBossMC  Injectionclass  MyService    include  TorqueBox::Injectors    def  initialize  opts={}        @heroin  =  inject("SomeMCBean")    endend
  • 79. Why  MC  Beans?All  internal  plumbing  of  JBoss  AS  is  stitched  together  using  MC.    Grab  the  WebServer,  the  CacheManager,  whatevs.
  • 80. BENchmarksReal-­world  Rail  application:RedmineComparisons:TorqueBox,  Trinidad,  Glassfish,  Passenger,  Unicorn,  ThinRuntimes:JRuby,  MRI,  RubyEE
  • 81. BackStageDashboard  to  inspect  and  control  Ruby  components.And  a  RESTful  API.
  • 82. StompBoxEasy  Heroku-­esque  git-­based  deployments.
  • 83. Oh  yeah... It  works  on  Windows.
  • 84. Roadmap1.1  Stable2.0  Development  (based  on    JBoss  AS7)???  -­  you  tell  us
  • 85. Resources• http://torquebox.org/• http://github.com/torquebox• #torquebox  on  FreeNode• @torquebox
  • 86. Thanks! Questions?                        Image  attributions: Target  by  Jasper  Johns  by  nostri-­imago  http://www.flickr.com/photos/nostri-­imago/3137422976/  CC  BY  2.0 WEB 2.0 HAS AN API  by  raster  http://www.flickr.com/photos/raster/137506981/  CC  BY-­NC-­SA  2.0 Clock  by  Earls37a  http://www.flickr.com/photos/indraw/4857101224/  CC  BY-­SA  2.0 Sink.  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.0 Service as a Strategy Celebration at NCVS 2011  by  Be  The  Change,  Inc  http://www.flickr.com/photos/bethechangeinc/5816393052/  CC  BY-­NC  2.0 Cash  by  ROSS  HONG  KONG  http://www.flickr.com/photos/rossap/2716531616/  CC  BY-­NC-­SA  2.0 Injection  by  Dr  Case  http://www.flickr.com/photos/justin_case/3252846177/  CC  BY-­NC  2.0 IMG_1478  by  akshaydavis  http://www.flickr.com/photos/akshaydavis/166391476/  CC  BY-­NC-­SA  2.0 Rainforest  by  Chris.Gray  http://www.flickr.com/photos/chriscgray/3946304802/  CC  BY-­NC-­SA  2.0 Community  by  niallkennedy  http://www.flickr.com/photos/niallkennedy/40727794/  CC  BY-­NC  2.0

×