SlideShare a Scribd company logo
1 of 81
Download to read offline
Complex  Made  Simple
 Sleep Better With TorqueBox
                 Bob  McWhirter
                 Director  of  Polyglot
                 Red  Hat




                                Creative  Commons  BY-­SA  3.0
Complex  Made  Simple
 Sleep Better With TorqueBox
                 Bob  McWhirter
                 Director  of  Polyglot
                 Red  Hat




                                Creative  Commons  BY-­SA  3.0
Who  am  I?

Bob  McWhirter
๏   Director  of  Polyglot,  JBoss  Fellow  @  Red  Hat
๏   TorqueBox  project  founder
๏   Part  of  the  project:odd  team
๏   The  Codehaus,  Drools,  Jaxen,  Groovy
Scenario

You've  got  a  Rails  
application  to  deploy,  
for  production.
But...


The  app  you  deploy  today  
will  grow  in  the  future,  if  
you’re  successful.
Deploy  Continuum



            TorqueBox
   Roll!                  Platform
 your!own               as!a!Service
What  is  TorqueBox?

TorqueBox  is  a  
Ruby  Application  Server.

Based  on  JRuby  and  
JBoss  AS7.
What  is  an  app-­server?

If  you’re  not  from  the  Java  world...
An  application  server  is  a  process  
that  hosts  your  app  and  
provides  a  multitude  of  services  
and  facilities.
App-­servertastic!


     Cache                   Jobs
              Application



        Web                 HA

               Queues
Anyhow...
Roll  your  own

๏ Install  OS
๏ Install  packages

๏ Configure  everything

๏ Manage  everything
Roll  your  own
๏   Apache  httpd
๏   Load  balancer
๏   Unicorn,  pack  of  Mongrels
๏   crontab
๏   SMTP
๏   memcached
๏   Database
๏   deployment
๏   monitoring
Or  outsource  
    some...
Roll  your  own  >>

๏ Install  OS
๏ Install  packages

๏ Configure  most  things

๏ Manage  most  things

๏ Outsource  some  things
Roll  your  own  >>
๏   Apache  httpd
๏   Load  balancer
๏   Unicorn,  pack  of  Mongrels
๏   crontab
๏   SMTP  Amazon  SES,  SendGrid
๏   memcached
๏   Database
๏   deployment  Capistrano
๏   monitoring  New  Relic
Use  a  Paas  (Heroku)


Outsource  everything  
but  your  app.
Heroku
๏   Apache  httpd  Heroku
๏   Load  balancer  Heroku
๏   Unicorn,  pack  of  Mongrels  Heroku
๏   crontab  Heroku
๏   SMTP  SendGrid
๏   memcached  Heroku
๏   Database  Heroku
๏   deployment  Heroku
๏   monitoring  New  Relic
Or  middle-­ground

๏ Decrease  number  of  things  to  manage
๏ Increase  scalability

๏ Increase  availability  (optionally)
TorqueBox
๏   Apache  httpd
๏   Load  balancer  JBoss  mod_cluster
๏   Unicorn,  pack  of  Mongrels  TorqueBox
๏   crontab  TorqueBox
๏   SMTP  Amazon  SES,  SendGrid
๏   memcached  TorqueBox
๏   Database
๏   deployment  Capistrano
๏   monitoring  NewRelic
Case  Study!
Appalachian  Sustainable  
Agriculture  Project  (ASAP)
Application  Needs
๏ Rails  2.x  web  app
๏ Caching

๏ Background  tasks

๏ Cron  jobs

๏ Deployment  from  SCM

๏ Sending  email

๏ Database  queries

๏ Monitoring  &  metrics
As  deployed  on  Heroku
Migration  Motivation

In  this  particular  case,  client  feels  it  
could  save  money,  and  have  a  better  
system  by  moving  to  an  affordable  VPS,  
letting  TorqueBox  absorb  some  of  the  
roll-­your-­own  complexity.
Migrating  to  TorqueBox



$  rvm  install  jruby-­1.6.7
Migrating  to  TorqueBox



$  gem  install  torquebox-­server  
    -­-­pre  -­-­version=2.0.0.cr1

     Simpler  once  we’re  no  longer  -­-­pre
Using  torquebox.rb  template




$  cd  myapp
$  torquebox  rails
torquebox.rb  template
๏   Add  torquebox  gems  to  Gemfile
๏   Add  activerecord-­jdbc-­adapter
๏   Add  torquebox-­rake-­support
๏   Create  directories  for  services,  jobs,  etc
๏   Initialize  web  session  store
๏   Initialize  Rails.cache  with  TorqueBox
๏   Initialize  ActiveRecord  for  background  jobs
“Porting”  the  
 application
Delayed::Job

App  uses  
Delayed::Job  

      Replace  with  TorqueBox  
      Backgroundable
Delayed  Job
  controller.rb


def  create
    @export  =  ExcelExport.create(...)
    job  =  ExcelExportJob.new  
    job.excel_export_id  =  @export.id
    Delayed::Job.enqueue  job
    @export.set_status  "Queued  for  Export"
    @export.save!
end
Delayed  Job
   excel_export_job.rb



class  ExcelExportJob  <  Struct.new(:excel_export_id)
    def  perform
        ExcelExport.find(self.excel_export_id).generate_report
    end
end
Delayed  Job
    excel_export.rb
class  ExcelExport  <  ActiveRecord::Base
    def  generate_report
        begin
            set_status  'Processing'
            spreadsheet  =  Spreadsheet.new(self.businesses)
        
            set_status  'Writing'
            spreadsheet.write_workbook  self.workbook_file

            set_status  'Storing  on  Amazon  S3'
            File.open(self.workbook_file)  {|out|self.output  =  out}
        
            set_status  'Cleaning  Up'
            File.delete(self.workbook_file)
        
            set_status  'Complete'
        rescue
            set_status  'Export  Error'
        end
    end
Delayed  Job


Mayhap  you  need  to  
run  a  worker,  also...
Delayed::Job

  Exporter < AR::Base   Database




  ExportJob < Struct     Worker
That's  pretty  explicit


TorqueBox  allows  you  to  
very  easily  run  methods  
asynchronously.
Backgroundable
   excel_export.rb

class  ExcelExport  <  ActiveRecord::Base
    always_background  :generate_report

    def  generate_report
        begin
            set_status  'Processing'
            ...
        rescue
            set_status  'Export  Error'
        end
    end

end    
Backgroundable
   excel_export.rb

class  ExcelExport  <  ActiveRecord::Base
    always_background  :generate_report

    def  generate_report
        begin
            set_status  'Processing'
            ...
        rescue
            set_status  'Export  Error'
        end
    end

end    
Backgroundable
  export_controller.rb



def  create
    @export  =  ExcelExport.create(...)
    @export.set_status  "Queued  for  Export"
    @export.save
    @export.generate_report
end
Backgroundable
 excel_export_job.rb




$  rm  excel_export_job.rb

                              it !
                       K ill
Trade!
Trade  some  code  and  
a  process  you  have  to  
manage  for  less  code  
and  an  in-­container  
service.
Backgroundable
 Implicit!magic!

            Queue           Processor




      Exporter < AR::Base   Database




      ExportJob < Struct     Worker
Caching

๏   template.rb  does  most  of  the  work
    ๏ Web  sessions

    ๏ Fragment  and  other  caching
No  more  
memcached!
Scheduled  Jobs
๏ Replaces  cron  jobs
๏ Deploys  with  your  application

๏ Includes  application  environment

๏ Cron-­like  scheduling

๏ HA-­clustering  (optionally)
Heroku  Cron

๏ Free  version  runs  1x  daily
๏ Implemented  as  a  rake  task

๏ Includes  application  environment
Roll  your  own

๏ crontab
๏ script/runner  (boots  rails  every  time)

๏ deployment  strategy
๏ source  control

๏ etc.
On  Heroku
   Rakefile

desc  "This  task  is  called  by  the  heroku  cron  add-­on"
task  :cron  =>  [:environment,  
                              :heroku_backup,  
                              :refresh_trip_planner]  

desc  "Refresh  the  trip  planner  business  data  cache"
task  :refresh_trip_planner  =>  :environment  do
    #
    #  update  GIS  cache
    #
end
Scheduled  Jobs


In  TorqueBox,  a  scheduled  job  is  a  
component  of  your  application.
Straight-­forward
  refresh_trip_planner.rb

class  RefreshTripPlanner
    def  run()
        #
        #  update  the  GIS  cache
        #
    end
end
Configuration
  torquebox.yml



jobs:
    cache.updater:
        job:                  RefreshTripPlanner
        cron:                '0  0  2  *  *  ?'
        description:  Refresh  trip  cache
But...

Doing  a  huge  query  
once-­a-­day  isn't  ideal,  
it  was  just  "free".
TorqueBox  Services


๏Avoid  the  huge  query
๏Keep  data  more  fresher
Keep  it  fresher
    trip_planner_service.rb
  TripPlannerService
    def  initialize(  options={}  )
        @queue  =  TorqueBox::Messaging::Queue.new(  '/queues/trip_planner'  )
    end
    
    def  start
        Thread.new  do
            initialize_cache
            while  should_run
                update_cache  @queue.receive
            end
        end
    end

    def  update_cache(  business_id  )
        TripPlanner.insert_or_update  business_id
    end
    #  initialize_cache(),  stop(),  etc
end
Keep  it  fresher
    trip_planner_service.rb
  TripPlannerService
    def  initialize(  options={}  )
  def  initialize(  options={}  )
        @queue  =  TorqueBox::Messaging::Queue.new(  '/queues/trip_planner'  )
      @queue  =  TorqueBox::Messaging::Queue.new(  ...  )
    end
  end
    
    def  start
        Thread.new  do
            initialize_cache
            while  should_run
                update_cache  @queue.receive
            end
        end
    end

    def  update_cache(  business_id  )
        TripPlanner.insert_or_update  business_id
    end
    #  initialize_cache(),  stop(),  etc
end
Keep  it  fresher
    trip_planner_service.rb
  TripPlannerService
    def  initialize(  options={}  )
                def  start
        @queue  =  TorqueBox::Messaging::Queue.new(  '/queues/trip_planner'  )
    end
                    Thread.new  do
    def  start          initialize_cache
        Thread.new  do
                        while  should_run
            initialize_cache
            while  should_run
                            update_cache  @queue.receive
                update_cache  @queue.receive
            end
        end             end
    end
                    end
                end
    def  update_cache(  business_id  )
        TripPlanner.insert_or_update  business_id
    end
    #  initialize_cache(),  stop(),  etc
end
Keep  it  fresher
      app/models/business.rb

require  'torquebox-­messaging'

class  Business  <  ActiveRecord::Base

    after_save  :update_trip_planner

    def  update_trip_planner
        queue  =  TorqueBox::Messaging::Queue.new('/queues/trip_planner')
        queue.publish(  self.id  )
    end

end
Keep  it  fresher
      app/models/business.rb

require  'torquebox-­messaging'

class  Business  <  ActiveRecord::Base

    after_save  :update_trip_planner

    def  update_trip_planner
         queue  =  TorqueBox::Messaging::Queue.new(...)
        queue  =  TorqueBox::Messaging::Queue.new('/queues/trip_planner')
        queue.publish(  self.id  )
    end
         queue.publish(  self.id  )

end
Queue,  Service,  Cache
                       Queue

 Non-blocking

        ActiveRecord
       Business                Service



                               Cache
Production!
(Remember,  we  work  for  Red  Hat)
Set  up  the  server
$  yum  install  
        java-­1.6.0-­openjdk  
        httpd  
        mod_cluster  
        git  
        postgresql-­server
Capistrano


Regular  capistrano  deployments  are  
supported  given  the  recipes  provided  by  
torquebox-­capistrano-­support.gem
Capistrano
   deploy.rb


require 'torquebox-capistrano-support'
require 'bundler/capistrano'

# source code
set :application,       "buyappalachian.org"
set :repository,        "git@github.com:account/repo.git"
set :branch,            "torquebox-2.0"
set :user,              "torquebox"
set :scm,               :git
set :scm_verbose,       true
set :use_sudo,          false
Capistrano
   deploy.rb  (continued)

# Production server
set :deploy_to,           "/opt/apps/buyappalachian.org"
set :torquebox_home,      "/opt/torquebox/current"
set :jboss_init_script,   "/etc/init.d/jboss-as-standalone"
set :app_environment,     "RAILS_ENV: production"
set :app_context,         "/"

ssh_options[:forward_agent] = false

role :web, "torquebox.buyappalachian.org"
role :app, "torquebox.buyappalachian.org"
role :db, "torquebox.buyappalachian.org",
     :primary => true
Launch  on  boot
init.d


Install  
/etc/init.d/jboss-­as
from  the  stock  distribution
JBoss  configuration
    /etc/jboss-­as/jboss-­as.conf

#   General configuration for the init.d script
#   Place this file in /etc/jboss-as/jboss-as.conf
#   and copy $JBOSS_HOME/bin/init.d/jboss-as-standalone.sh
#   to /etc/init.d/jboss-as-standalone

JBOSS_USER=torquebox
JBOSS_HOME=/opt/torquebox/current/jboss
JBOSS_PIDFILE=/var/run/torquebox/torquebox.pid
JBOSS_CONSOLE_LOG=/var/log/torquebox/console.log
JBOSS_CONFIG=standalone-ha.xml
Load  Balance  with  
  mod_cluster
mod_cluster
   httpd.conf


LoadModule  slotmem_module              modules/mod_slotmem.so
LoadModule  proxy_cluster_module  modules/mod_proxy_cluster.so
LoadModule  advertise_module          modules/mod_advertise.so
LoadModule  manager_module              modules/mod_manager.so

<Location  /mod_cluster_manager>
        SetHandler  mod_cluster-­manager
        AllowDisplay  On
</Location>

Listen  torquebox-­balancer:6666
mod_cluster
   httpd.conf  (continued)
<VirtualHost  torquebox-­balancer:6666>
  
    <Directory  />
        Order  deny,allow
        Deny  from  all
        Allow  from  all
    </Directory>
  
    KeepAliveTimeout  60
    MaxKeepAliveRequests  0

    EnableMCPMReceive
  
    ManagerBalancerName  torquebox-­balancer
    AllowDisplay  On
    AdvertiseFrequency  5
    AdvertiseSecurityKey  secret
  
</VirtualHost>
Deployed


[root@torquebox  opt]#  ls  -­l  apps/buyappalachian.org/
total  8
lrwxrwxrwx  1      23  Mar  16  15:10  current  -­>  releases/20120315230553
drwxrwxr-­x  5  4096  Mar  15  19:05  releases
drwxrwxr-­x  6  4096  Mar  15  17:29  shared
And  then  it  grows...

As  your  app  evolves,  you  might  
add  stuff  like  WebSockets/STOMP,  
or  HA  or  other  facilities  already  in  
the  tin.
Can  we  go  
 further?
What's  a  PaaS?


     Cache                     Jobs
              Application



         DB                 Email

               Queues
TorqueBox  on  OpenShift




     openshift.redhat.com
Roadmap  &  Status

๏ Current  2.0.0.CR1
๏ 2.0.0.Final  Real  Flippin’  Soon

๏ Continuing  investment  from  Red  Hat

๏ Interop  with  other  languages,  such  
  as  Clojure  via  Immutant
Resources

http://torquebox.org/

@torquebox  on  Twitter

#torquebox  on  IRC
Question  
everything.
Creative  Commons  BY-­SA  3.0

More Related Content

What's hot

JUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxJUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxmarekgoldmann
 
JUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrinderJUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrindermarekgoldmann
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosBruno Oliveira
 
TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011Lance Ball
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011tobiascrawley
 
Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011tobiascrawley
 
When Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the EnterpriseWhen Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the Enterprisebenbrowning
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyNick Sieger
 
The Enterprise Strikes Back
The Enterprise Strikes BackThe Enterprise Strikes Back
The Enterprise Strikes BackBurke Libbey
 
Introduction to Apache Camel
Introduction to Apache CamelIntroduction to Apache Camel
Introduction to Apache CamelFuseSource.com
 
Ruby 1.9 Fibers
Ruby 1.9 FibersRuby 1.9 Fibers
Ruby 1.9 FibersKevin Ball
 
Using Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBUsing Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBHiro Asari
 
Apache camel overview dec 2011
Apache camel overview dec 2011Apache camel overview dec 2011
Apache camel overview dec 2011Marcelo Jabali
 
Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 
Fiber in the 10th year
Fiber in the 10th yearFiber in the 10th year
Fiber in the 10th yearKoichi Sasada
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)ngotogenome
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developergicappa
 

What's hot (20)

JUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxJUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBox
 
JUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrinderJUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrinder
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundos
 
TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
 
Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011
 
When Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the EnterpriseWhen Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the Enterprise
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRuby
 
The Enterprise Strikes Back
The Enterprise Strikes BackThe Enterprise Strikes Back
The Enterprise Strikes Back
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
Introduction to Apache Camel
Introduction to Apache CamelIntroduction to Apache Camel
Introduction to Apache Camel
 
Ruby 1.9 Fibers
Ruby 1.9 FibersRuby 1.9 Fibers
Ruby 1.9 Fibers
 
Using Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBUsing Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRB
 
JRuby and You
JRuby and YouJRuby and You
JRuby and You
 
First Day With J Ruby
First Day With J RubyFirst Day With J Ruby
First Day With J Ruby
 
Apache camel overview dec 2011
Apache camel overview dec 2011Apache camel overview dec 2011
Apache camel overview dec 2011
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 
Fiber in the 10th year
Fiber in the 10th yearFiber in the 10th year
Fiber in the 10th year
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developer
 

Similar to Complex Made Simple: Sleep Better with TorqueBox

Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Masahiro Nagano
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmsom_nangia
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmwilburlo
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesHiroshi SHIBATA
 
Fisl - Deployment
Fisl - DeploymentFisl - Deployment
Fisl - DeploymentFabio Akita
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
Migrating Legacy Data (Ruby Midwest)
Migrating Legacy Data (Ruby Midwest)Migrating Legacy Data (Ruby Midwest)
Migrating Legacy Data (Ruby Midwest)Patrick Crowley
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby TeamArto Artnik
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppSmartLogic
 

Similar to Complex Made Simple: Sleep Better with TorqueBox (20)

Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Rack
RackRack
Rack
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutes
 
Fisl - Deployment
Fisl - DeploymentFisl - Deployment
Fisl - Deployment
 
Sprockets
SprocketsSprockets
Sprockets
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Migrating Legacy Data (Ruby Midwest)
Migrating Legacy Data (Ruby Midwest)Migrating Legacy Data (Ruby Midwest)
Migrating Legacy Data (Ruby Midwest)
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Capistrano
CapistranoCapistrano
Capistrano
 

Recently uploaded

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 

Recently uploaded (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 

Complex Made Simple: Sleep Better with TorqueBox

  • 1. Complex  Made  Simple Sleep Better With TorqueBox Bob  McWhirter Director  of  Polyglot Red  Hat Creative  Commons  BY-­SA  3.0
  • 2. Complex  Made  Simple Sleep Better With TorqueBox Bob  McWhirter Director  of  Polyglot Red  Hat Creative  Commons  BY-­SA  3.0
  • 3. Who  am  I? Bob  McWhirter ๏ Director  of  Polyglot,  JBoss  Fellow  @  Red  Hat ๏ TorqueBox  project  founder ๏ Part  of  the  project:odd  team ๏ The  Codehaus,  Drools,  Jaxen,  Groovy
  • 4. Scenario You've  got  a  Rails   application  to  deploy,   for  production.
  • 5. But... The  app  you  deploy  today   will  grow  in  the  future,  if   you’re  successful.
  • 6. Deploy  Continuum TorqueBox Roll! Platform your!own as!a!Service
  • 7. What  is  TorqueBox? TorqueBox  is  a   Ruby  Application  Server. Based  on  JRuby  and   JBoss  AS7.
  • 8. What  is  an  app-­server? If  you’re  not  from  the  Java  world... An  application  server  is  a  process   that  hosts  your  app  and   provides  a  multitude  of  services   and  facilities.
  • 9. App-­servertastic! Cache Jobs Application Web HA Queues
  • 11. Roll  your  own ๏ Install  OS ๏ Install  packages ๏ Configure  everything ๏ Manage  everything
  • 12. Roll  your  own ๏ Apache  httpd ๏ Load  balancer ๏ Unicorn,  pack  of  Mongrels ๏ crontab ๏ SMTP ๏ memcached ๏ Database ๏ deployment ๏ monitoring
  • 13. Or  outsource   some...
  • 14. Roll  your  own  >> ๏ Install  OS ๏ Install  packages ๏ Configure  most  things ๏ Manage  most  things ๏ Outsource  some  things
  • 15. Roll  your  own  >> ๏ Apache  httpd ๏ Load  balancer ๏ Unicorn,  pack  of  Mongrels ๏ crontab ๏ SMTP  Amazon  SES,  SendGrid ๏ memcached ๏ Database ๏ deployment  Capistrano ๏ monitoring  New  Relic
  • 16. Use  a  Paas  (Heroku) Outsource  everything   but  your  app.
  • 17. Heroku ๏ Apache  httpd  Heroku ๏ Load  balancer  Heroku ๏ Unicorn,  pack  of  Mongrels  Heroku ๏ crontab  Heroku ๏ SMTP  SendGrid ๏ memcached  Heroku ๏ Database  Heroku ๏ deployment  Heroku ๏ monitoring  New  Relic
  • 18. Or  middle-­ground ๏ Decrease  number  of  things  to  manage ๏ Increase  scalability ๏ Increase  availability  (optionally)
  • 19. TorqueBox ๏ Apache  httpd ๏ Load  balancer  JBoss  mod_cluster ๏ Unicorn,  pack  of  Mongrels  TorqueBox ๏ crontab  TorqueBox ๏ SMTP  Amazon  SES,  SendGrid ๏ memcached  TorqueBox ๏ Database ๏ deployment  Capistrano ๏ monitoring  NewRelic
  • 22. Application  Needs ๏ Rails  2.x  web  app ๏ Caching ๏ Background  tasks ๏ Cron  jobs ๏ Deployment  from  SCM ๏ Sending  email ๏ Database  queries ๏ Monitoring  &  metrics
  • 23. As  deployed  on  Heroku
  • 24. Migration  Motivation In  this  particular  case,  client  feels  it   could  save  money,  and  have  a  better   system  by  moving  to  an  affordable  VPS,   letting  TorqueBox  absorb  some  of  the   roll-­your-­own  complexity.
  • 25. Migrating  to  TorqueBox $  rvm  install  jruby-­1.6.7
  • 26. Migrating  to  TorqueBox $  gem  install  torquebox-­server      -­-­pre  -­-­version=2.0.0.cr1 Simpler  once  we’re  no  longer  -­-­pre
  • 27. Using  torquebox.rb  template $  cd  myapp $  torquebox  rails
  • 28. torquebox.rb  template ๏ Add  torquebox  gems  to  Gemfile ๏ Add  activerecord-­jdbc-­adapter ๏ Add  torquebox-­rake-­support ๏ Create  directories  for  services,  jobs,  etc ๏ Initialize  web  session  store ๏ Initialize  Rails.cache  with  TorqueBox ๏ Initialize  ActiveRecord  for  background  jobs
  • 29. “Porting”  the   application
  • 30. Delayed::Job App  uses   Delayed::Job   Replace  with  TorqueBox   Backgroundable
  • 31. Delayed  Job controller.rb def  create    @export  =  ExcelExport.create(...)    job  =  ExcelExportJob.new      job.excel_export_id  =  @export.id    Delayed::Job.enqueue  job    @export.set_status  "Queued  for  Export"    @export.save! end
  • 32. Delayed  Job excel_export_job.rb class  ExcelExportJob  <  Struct.new(:excel_export_id)    def  perform        ExcelExport.find(self.excel_export_id).generate_report    end end
  • 33. Delayed  Job excel_export.rb class  ExcelExport  <  ActiveRecord::Base    def  generate_report        begin            set_status  'Processing'            spreadsheet  =  Spreadsheet.new(self.businesses)                    set_status  'Writing'            spreadsheet.write_workbook  self.workbook_file            set_status  'Storing  on  Amazon  S3'            File.open(self.workbook_file)  {|out|self.output  =  out}                    set_status  'Cleaning  Up'            File.delete(self.workbook_file)                    set_status  'Complete'        rescue            set_status  'Export  Error'        end    end
  • 34. Delayed  Job Mayhap  you  need  to   run  a  worker,  also...
  • 35. Delayed::Job Exporter < AR::Base Database ExportJob < Struct Worker
  • 36. That's  pretty  explicit TorqueBox  allows  you  to   very  easily  run  methods   asynchronously.
  • 37. Backgroundable excel_export.rb class  ExcelExport  <  ActiveRecord::Base    always_background  :generate_report    def  generate_report        begin            set_status  'Processing'            ...        rescue            set_status  'Export  Error'        end    end end    
  • 38. Backgroundable excel_export.rb class  ExcelExport  <  ActiveRecord::Base    always_background  :generate_report    def  generate_report        begin            set_status  'Processing'            ...        rescue            set_status  'Export  Error'        end    end end    
  • 39. Backgroundable export_controller.rb def  create    @export  =  ExcelExport.create(...)    @export.set_status  "Queued  for  Export"    @export.save    @export.generate_report end
  • 40. Backgroundable excel_export_job.rb $  rm  excel_export_job.rb  it ! K ill
  • 41. Trade! Trade  some  code  and   a  process  you  have  to   manage  for  less  code   and  an  in-­container   service.
  • 42. Backgroundable Implicit!magic! Queue Processor Exporter < AR::Base Database ExportJob < Struct Worker
  • 43. Caching ๏ template.rb  does  most  of  the  work ๏ Web  sessions ๏ Fragment  and  other  caching
  • 45. Scheduled  Jobs ๏ Replaces  cron  jobs ๏ Deploys  with  your  application ๏ Includes  application  environment ๏ Cron-­like  scheduling ๏ HA-­clustering  (optionally)
  • 46. Heroku  Cron ๏ Free  version  runs  1x  daily ๏ Implemented  as  a  rake  task ๏ Includes  application  environment
  • 47. Roll  your  own ๏ crontab ๏ script/runner  (boots  rails  every  time) ๏ deployment  strategy ๏ source  control ๏ etc.
  • 48. On  Heroku Rakefile desc  "This  task  is  called  by  the  heroku  cron  add-­on" task  :cron  =>  [:environment,                                :heroku_backup,                                :refresh_trip_planner]   desc  "Refresh  the  trip  planner  business  data  cache" task  :refresh_trip_planner  =>  :environment  do    #    #  update  GIS  cache    # end
  • 49. Scheduled  Jobs In  TorqueBox,  a  scheduled  job  is  a   component  of  your  application.
  • 50. Straight-­forward refresh_trip_planner.rb class  RefreshTripPlanner    def  run()        #        #  update  the  GIS  cache        #    end end
  • 51. Configuration torquebox.yml jobs:    cache.updater:        job:                  RefreshTripPlanner        cron:                '0  0  2  *  *  ?'        description:  Refresh  trip  cache
  • 52. But... Doing  a  huge  query   once-­a-­day  isn't  ideal,   it  was  just  "free".
  • 53. TorqueBox  Services ๏Avoid  the  huge  query ๏Keep  data  more  fresher
  • 54. Keep  it  fresher trip_planner_service.rb  TripPlannerService    def  initialize(  options={}  )        @queue  =  TorqueBox::Messaging::Queue.new(  '/queues/trip_planner'  )    end        def  start        Thread.new  do            initialize_cache            while  should_run                update_cache  @queue.receive            end        end    end    def  update_cache(  business_id  )        TripPlanner.insert_or_update  business_id    end    #  initialize_cache(),  stop(),  etc end
  • 55. Keep  it  fresher trip_planner_service.rb  TripPlannerService    def  initialize(  options={}  ) def  initialize(  options={}  )        @queue  =  TorqueBox::Messaging::Queue.new(  '/queues/trip_planner'  )    @queue  =  TorqueBox::Messaging::Queue.new(  ...  )    end end        def  start        Thread.new  do            initialize_cache            while  should_run                update_cache  @queue.receive            end        end    end    def  update_cache(  business_id  )        TripPlanner.insert_or_update  business_id    end    #  initialize_cache(),  stop(),  etc end
  • 56. Keep  it  fresher trip_planner_service.rb  TripPlannerService    def  initialize(  options={}  ) def  start        @queue  =  TorqueBox::Messaging::Queue.new(  '/queues/trip_planner'  )    end        Thread.new  do    def  start        initialize_cache        Thread.new  do        while  should_run            initialize_cache            while  should_run            update_cache  @queue.receive                update_cache  @queue.receive            end        end        end    end    end end    def  update_cache(  business_id  )        TripPlanner.insert_or_update  business_id    end    #  initialize_cache(),  stop(),  etc end
  • 57. Keep  it  fresher app/models/business.rb require  'torquebox-­messaging' class  Business  <  ActiveRecord::Base    after_save  :update_trip_planner    def  update_trip_planner        queue  =  TorqueBox::Messaging::Queue.new('/queues/trip_planner')        queue.publish(  self.id  )    end end
  • 58. Keep  it  fresher app/models/business.rb require  'torquebox-­messaging' class  Business  <  ActiveRecord::Base    after_save  :update_trip_planner    def  update_trip_planner queue  =  TorqueBox::Messaging::Queue.new(...)        queue  =  TorqueBox::Messaging::Queue.new('/queues/trip_planner')        queue.publish(  self.id  )    end queue.publish(  self.id  ) end
  • 59. Queue,  Service,  Cache Queue Non-blocking ActiveRecord Business Service Cache
  • 61.
  • 62. (Remember,  we  work  for  Red  Hat)
  • 63. Set  up  the  server $  yum  install          java-­1.6.0-­openjdk          httpd          mod_cluster          git          postgresql-­server
  • 64. Capistrano Regular  capistrano  deployments  are   supported  given  the  recipes  provided  by   torquebox-­capistrano-­support.gem
  • 65. Capistrano deploy.rb require 'torquebox-capistrano-support' require 'bundler/capistrano' # source code set :application, "buyappalachian.org" set :repository, "git@github.com:account/repo.git" set :branch, "torquebox-2.0" set :user, "torquebox" set :scm, :git set :scm_verbose, true set :use_sudo, false
  • 66. Capistrano deploy.rb  (continued) # Production server set :deploy_to, "/opt/apps/buyappalachian.org" set :torquebox_home, "/opt/torquebox/current" set :jboss_init_script, "/etc/init.d/jboss-as-standalone" set :app_environment, "RAILS_ENV: production" set :app_context, "/" ssh_options[:forward_agent] = false role :web, "torquebox.buyappalachian.org" role :app, "torquebox.buyappalachian.org" role :db, "torquebox.buyappalachian.org", :primary => true
  • 69. JBoss  configuration /etc/jboss-­as/jboss-­as.conf # General configuration for the init.d script # Place this file in /etc/jboss-as/jboss-as.conf # and copy $JBOSS_HOME/bin/init.d/jboss-as-standalone.sh # to /etc/init.d/jboss-as-standalone JBOSS_USER=torquebox JBOSS_HOME=/opt/torquebox/current/jboss JBOSS_PIDFILE=/var/run/torquebox/torquebox.pid JBOSS_CONSOLE_LOG=/var/log/torquebox/console.log JBOSS_CONFIG=standalone-ha.xml
  • 70. Load  Balance  with   mod_cluster
  • 71. mod_cluster httpd.conf LoadModule  slotmem_module              modules/mod_slotmem.so LoadModule  proxy_cluster_module  modules/mod_proxy_cluster.so LoadModule  advertise_module          modules/mod_advertise.so LoadModule  manager_module              modules/mod_manager.so <Location  /mod_cluster_manager>        SetHandler  mod_cluster-­manager        AllowDisplay  On </Location> Listen  torquebox-­balancer:6666
  • 72. mod_cluster httpd.conf  (continued) <VirtualHost  torquebox-­balancer:6666>      <Directory  />        Order  deny,allow        Deny  from  all        Allow  from  all    </Directory>      KeepAliveTimeout  60    MaxKeepAliveRequests  0    EnableMCPMReceive      ManagerBalancerName  torquebox-­balancer    AllowDisplay  On    AdvertiseFrequency  5    AdvertiseSecurityKey  secret   </VirtualHost>
  • 73. Deployed [root@torquebox  opt]#  ls  -­l  apps/buyappalachian.org/ total  8 lrwxrwxrwx  1      23  Mar  16  15:10  current  -­>  releases/20120315230553 drwxrwxr-­x  5  4096  Mar  15  19:05  releases drwxrwxr-­x  6  4096  Mar  15  17:29  shared
  • 74. And  then  it  grows... As  your  app  evolves,  you  might   add  stuff  like  WebSockets/STOMP,   or  HA  or  other  facilities  already  in   the  tin.
  • 75. Can  we  go   further?
  • 76. What's  a  PaaS? Cache Jobs Application DB Email Queues
  • 77. TorqueBox  on  OpenShift openshift.redhat.com
  • 78. Roadmap  &  Status ๏ Current  2.0.0.CR1 ๏ 2.0.0.Final  Real  Flippin’  Soon ๏ Continuing  investment  from  Red  Hat ๏ Interop  with  other  languages,  such   as  Clojure  via  Immutant