When Java meets Ruby


     Creative Commons BY-SA 3.0




Thursday, December 8, 11
@abstractj
          Java há 12 anos, Ruby n00b
          TorqueBox Contributor
          DynJS Contributor
          Caelum & ConcreteS


Thursday, December 8, 11
DISCLAIMER



Thursday, December 8, 11
Java

                   927 JSRS!
               nooooooooooooooo!

Thursday, December 8, 11
import java.util.Calendar;
                           public class Beer {
                             private Long beerId;
                             private String description;
                             private Calendar createdAt;
                             public Long getBeerId() {
                                return beerId;
                             }
                             public void setBeerId(Long beerId) {

Expressiva?                  }
                                this.beerId = beerId;

                             public String getDescription() {
                                return description;
                             }
                             public void setDescription(String description)
                                this.description = description;
                             }
                             public Calendar getCreatedAt() {
                                return createdAt;
                             }
                             public void setCreatedAt(Calendar createdAt)
                                this.createdAt = createdAt;
                             }
Thursday, December 8, 11
                           }
ENTERPRISE



Thursday, December 8, 11
JAXR                         Java-FX     JAXP
                           JSTL                         StAX JME
                                  JDOM       JVM
         JAX-RPC                                      EJB
                                              AWT           JMX
                  Swing
      EAR Struts          JAAS                        JCP
                 JavaBean
         NPE                                                Spring
     JAX-WS                  ENTERPRISE                        RMI
           JSE               JNI      JNDI               NIO
                                                   SOA          JSP
      JSF JAXB                          WAR             JDO
  JAX-RS JPQL                                  JAF         POJO
               EJBQL                                  JRE
    JEE

Thursday, December 8, 11
Thursday, December 8, 11
Mas escala né?!




Thursday, December 8, 11
Scala            Clojure
                                   Jython


                                    JVM
                                    DynJS
                  Rhino                     Groovy




Thursday, December 8, 11
Ruby
     Mais expressiva que Java

      class Beer
        attr_accessor :beer_id, :description, :created_at
      end




Thursday, December 8, 11
DRY



       “It is tempting, if the only tool you have is a
       hammer, to treat everything as if it were a
       nail.” - Abraham Maslow

Thursday, December 8, 11
JRuby
                           Java + Ruby




Thursday, December 8, 11
JRuby
    require 'java'

    pdf = com.itextpdf.text.Document.new
    para = com.itextpdf.text.Paragraph.new 'Brought to you by JRuby'
    file = java.io.FileOutputStream.new 'pdf_demo.pdf'
    com.itextpdf.text.pdf.PdfWriter.get_instance pdf, file

    pdf.open
    pdf.add para
    pdf.close




Thursday, December 8, 11
“You get true multithreading that
                can use all your computer’s cores
                from one process, plus a virtual
                machine that’s been tuned for a
                decade and a half.”

                            Using JRuby - Bringing Ruby to Java




Thursday, December 8, 11
Server Side



Thursday, December 8, 11
Ruby App
                             Sinatra      Rails
                                   Rack
                             Passenger/Thin


                             Apache/Nginx




Thursday, December 8, 11
Ruby App
                             Sinatra      Rails
                                   Rack
                             Passenger/Thin       Jobs


                             Apache/Nginx         crond




Thursday, December 8, 11
Ruby App
                                      Sinatra      Rails
                                            Rack
                           Tasks      Passenger/Thin       Jobs
                        Resque/
                       DelayedJob     Apache/Nginx         crond




Thursday, December 8, 11
Ruby App
                                      Sinatra      Rails
                                            Rack
                           Tasks      Passenger/Thin       Jobs
                        Resque/
                       DelayedJob     Apache/Nginx         crond


                                         Daemons


                                       god/monit



Thursday, December 8, 11
JBoss
     Tomcat




Thursday, December 8, 11
JBoss
     HornetQ




Thursday, December 8, 11
JBoss
     Quartz




Thursday, December 8, 11
JBoss
     Clustering




Thursday, December 8, 11
AS 7
     Redução do footprint de memória
     Class loader modular
     Queda no tempo de startup
     EE6 compliant




Thursday, December 8, 11
TorqueBox
                           “The power of JBoss with the
                             expressiveness of Ruby”
                                       Jim Crossley - MagicRuby Conference




Thursday, December 8, 11
TorqueBox




Thursday, December 8, 11
Instalação
                            TorqueBox do zero




Thursday, December 8, 11
Pré-requisitos
      ➜ java -version
      java version "1.6.0_07"
      Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153)
      Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57,
      mixed mode)




Thursday, December 8, 11
➜ jruby -S gem install torquebox torquebox-capistrano-support




Thursday, December 8, 11
➜ wget http://repository-torquebox.forge.cloudbees.com/
     release/org/torquebox/torquebox-dist/2.0.0.beta1/torquebox-
     dist-2.0.0.beta1-bin.zip
     ➜ unzip torquebox-dist-2.0.0.beta1-bin.zip

     ➜ export TORQUEBOX_HOME=$PWD/torquebox-
     dist-2.0.0.beta1
     ➜ export JBOSS_HOME=$TORQUEBOX_HOME/jboss
     ➜ export JRUBY_HOME=$TORQUEBOX_HOME/jruby

     ➜ export PATH=$JRUBY_HOME/bin:$PATH




Thursday, December 8, 11
Rails
     rails new beer -m $TORQUEBOX_HOME/share/rails/template.rb




Thursday, December 8, 11
Estrutura
     Diretórios do TorqueBox




Thursday, December 8, 11
Rake tasks
      rake torquebox:deploy
      rake torquebox:undeploy
      rake torquebox:run




Thursday, December 8, 11
Deployment
                           Make knobs, not WAR!




Thursday, December 8, 11
beer-knob.yml
     application:
      root: /Users/Bruno/javaonebrasil/beer
      environment: development




Thursday, December 8, 11
Thursday, December 8, 11
Aplicação



Thursday, December 8, 11
source "http://torquebox.org/2x/builds/584/gem-
                           repo"
                           source 'http://rubygems.org'

                           gem 'rails', '3.1.1'



     Gemfile
                           gem 'activerecord-jdbcsqlite3-adapter'

                           gem 'jruby-openssl'
                           gem 'json'
                           gem 'jquery-rails'

                           gem "torquebox-rake-support", "2.x.incremental.
                           584"
                           gem "torquebox", "2.x.incremental.584"




Thursday, December 8, 11
Web
                           Rack, Sinatra, Rails




Thursday, December 8, 11
Caching
     class BeersController < ApplicationController

        caches_action :most_popular, :expires_in => 30.seconds

        def most_popular
         @popular_beers = Beer.most_popular(:limit => 25)
        end

     end




Thursday, December 8, 11
Thursday, December 8, 11
Clustering
     ➜ torquebox run --clustered




Thursday, December 8, 11
Internals
     class TorqueBoxCommand < Thor
      TASK_ORDER = %w(deploy undeploy start cli env help)

      map "run" => "start"
      desc "run", "Run TorqueBox"
      method_option :clustered,
                     :type => :boolean,
                     :desc => "Run TorqueBox in clustered mode"
      def start
       setup_environment
       TorqueBox::DeployUtils.run_server(:clustered => options.clustered,
                           :max_threads => options['max-threads'],
                           :bind_address => options['bind-address'])
      end
     end




Thursday, December 8, 11
Cache distribuído!



Thursday, December 8, 11
mod_cluster
                           httpd-based load balancer




Thursday, December 8, 11
Infinispan
                             Caching




Thursday, December 8, 11
Invalidation
                            Cache     Cache
                           Server1   Server2




Thursday, December 8, 11
Invalidation
                                     Notificação
                            Cache                  Cache
                           Server1                Server2


                           NEW                   Cache
                                              Desatualizado




Thursday, December 8, 11
../config/application.rb
     module Beer

      class Application < Rails::Application
       config.cache_store = :torque_box_store
      end
     end




Thursday, December 8, 11
Replicated
                                             Cache
                                            Server2
                            Cache
                           Server1   Sync
                                             Cache
                                     Sync   Server2



                                             Cache
                                            Server2




Thursday, December 8, 11
../config/application.rb
     module Beer

      class Application < Rails::Application
       config.cache_store = :torque_box_store, {:mode =>
     replicated, :sync =>false}
      end
     end




Thursday, December 8, 11
Scheduling
                           Agendamento de Jobs




Thursday, December 8, 11
Internals
      public class RubyJobProxy implements Job {

          @Override
          public void execute(JobExecutionContext context) throws JobExecutionException {
            Ruby ruby = null;
            try {
               ruby = this.runtimePool.borrowRuntime( resolver.getComponentName() );
               JobComponent job = (JobComponent)resolver.resolve( ruby );
               job.run();
            } catch (Exception e) {
               throw new JobExecutionException( e );
            } finally {
               if (ruby != null) {
                   this.runtimePool.returnRuntime( ruby );
               }
            }
          }




Thursday, December 8, 11
Internals
      public class RubyJobProxy implements Job {

          @Override
          public void execute(JobExecutionContext context) throws JobExecutionException {
            Ruby ruby = null;
            try {
               ruby = this.runtimePool.borrowRuntime( resolver.getComponentName() );
               JobComponent job = (JobComponent)resolver.resolve( ruby );
               job.run();
            } catch (Exception e) {
               throw new JobExecutionException( e );
            } finally {
               if (ruby != null) {
                   this.runtimePool.returnRuntime( ruby );
               }
            }
          }




Thursday, December 8, 11
../app/jobs
     class JobDemo

         def initialize
          #Codigo de inicializacao
         end

      def run
       # O que você quer executar
      end
     end


Thursday, December 8, 11
../config/torquebox.yml
     jobs:
      sync_agenda:
       job: JobDemo
       cron: '0 0 12 * * ?'
     end




Thursday, December 8, 11
Mensageria
     Java Messaging Service + HornetQ




Thursday, December 8, 11
O Ministério da Saúde adverte:

                      NOSQL COMO MENSAGERIA
                                PODE
                     TRAZER DANOS A SUA SAÚDE
                       E A DE SEUS FAMILIARES




Thursday, December 8, 11
Greenfield
                                 REST + NoSQL

                                 Request/Responsext


                                     NoSQL

                    RAILS APP        pub/sub          SINATRA APP




Thursday, December 8, 11
Real World
                                  Nobody Cares!
                                   Request/Responsext


                                       NoSQL

                      RAILS APP        pub/sub          MAINFRAME




Thursday, December 8, 11
../config/torquebox.yml
     /topics/beerTopic
     /queues/queueBeer:




Thursday, December 8, 11
Tasks
     class EmailerTask < TorqueBox::Messaging::Task
      def send_welcome(payload)
       to = "#{payload[:name]} <#{payload[:address]}>"
       # send welcome email to the user
      end
     end




Thursday, December 8, 11
Tasks
     class UserController < ApplicationController
      def register
       user = User.new(params[:user])

       EmailerTask.async(:send_welcome, :address =>
     user.email, :name => user.name)
      end
     end




Thursday, December 8, 11
Processors
     include TorqueBox::Messaging

     class PrintHandler < MessageProcessor
       def on_message(body)
         puts "Processing #{body} of #{message}"
       end
       def configure(opts)
         @color = opts['color']
       end
     end




Thursday, December 8, 11
Queues
     include TorqueBox
     req = Messaging::Queue.new '/queues/questions'
     res = Messaging::Queue.new '/queues/answers'
      
     Thread.new do
       req.publish "What time is it?"
       puts res.receive( :timeout => 1000 )
     end




Thursday, December 8, 11
Future




Thursday, December 8, 11
Future
     class EmailerTask

      def send_welcome(payload)
       to = "#{payload[:name]} <#{payload[:address]}>"
       # long running task
      end
     end




Thursday, December 8, 11
Future
     class EmailerTask

         include TorqueBox::Messaging::Backgroundable
         always_background :send_welcome

      def send_welcome(payload)
       to = "#{payload[:name]} <#{payload[:address]}>"
       # long running task
      end
     end




Thursday, December 8, 11
Future
       future = @emailTask.send_welcome(:send_welcome)

       future.started?

       future.complete?

       future.error?

       future.result
       future.result(10000)




Thursday, December 8, 11
Services



Thursday, December 8, 11
Services
     class BeerService
      def initialize
       @queue = Messaging::Queue.new(“beer”)
      end
      def start
       @queue.publish “Testing”
      end
      def stop
       # O que fazer quando o serviço receber um stop
      end
     end




Thursday, December 8, 11
Singleton Services
                                     Clustered
                           Server1                  Server2




            BeerService                          BeerService




Thursday, December 8, 11
Singleton Services
                                     Clustered
                           Server1                  Server2




            BeerService                          BeerService




Thursday, December 8, 11
Services
     ➜ torquebox run --clustered



     ../config/torquebox.yml
     services:
      BeerService:
       singleton: true
     end




Thursday, December 8, 11
CDI
                           Injeção de dependências




Thursday, December 8, 11
Pra quê?



Thursday, December 8, 11
Java
     package br.com.javaonebrasil;

     public class Beer {
       //gets e sets
       public void say(String message) { // Execução do método }
     }

     Deploy do jar na aplicação
     app/
     models/
     views/
     controllers/
     lib/beer.jar




Thursday, December 8, 11
Ruby
     class BeerController < ApplicationController

          include TorqueBox::Injectors

          def create
           beer = inject(br.com.javaonebrasil.Beer )
           beer.say “Ruby is for Java”
          end

     end




Thursday, December 8, 11
JNDI
   class MyService
    include TorqueBox::Injectors

    def initialize opts={}
     @factory = inject("java:comp/env/jdbc/myDB")
    end
   end




Thursday, December 8, 11
Destinations
      class MyService
       include TorqueBox::Injectors

       def initialize opts={}
        @inbound = inject("/topic/beerpub")
        @outbound = inject("/queue/beer")
       end
      end




Thursday, December 8, 11
Transactions
          Queue               Database   Infinispan



                   Rails Application       Topic


        XA Distributed, multi resource transaction




Thursday, December 8, 11
XA (2PC)
      HornetQ ✔
      Infinispan ✔
       TorqueBox + ActiveRecord ✔




Thursday, December 8, 11
Outras features
     Autenticação + Websockets




Thursday, December 8, 11
BackStage




Thursday, December 8, 11
Stomp Box
                           TorqueBox deployment support




Thursday, December 8, 11
Thursday, December 8, 11
What’s next?



Thursday, December 8, 11
Polyglot
     Immutant

                           Queue   Queue

   TorqueBox




Thursday, December 8, 11
Getting started

                       Installing TorqueBox 2.0
                      http://vimeo.com/33299335



Thursday, December 8, 11
Comunidade
           irc.freenode.net #torquebox
           http://torquebox.org
           http://github.com/torquebox
           twitter: @torquebox

Thursday, December 8, 11
Obrigado!
                                            @abstractj
                                   http://github.com/abstractj



      Creative Commons BY-SA 3.0




Thursday, December 8, 11

TorqueBox - When Java meets Ruby

  • 1.
    When Java meetsRuby Creative Commons BY-SA 3.0 Thursday, December 8, 11
  • 2.
    @abstractj Java há 12 anos, Ruby n00b TorqueBox Contributor DynJS Contributor Caelum & ConcreteS Thursday, December 8, 11
  • 3.
  • 4.
    Java 927 JSRS! nooooooooooooooo! Thursday, December 8, 11
  • 5.
    import java.util.Calendar; public class Beer { private Long beerId; private String description; private Calendar createdAt; public Long getBeerId() { return beerId; } public void setBeerId(Long beerId) { Expressiva? } this.beerId = beerId; public String getDescription() { return description; } public void setDescription(String description) this.description = description; } public Calendar getCreatedAt() { return createdAt; } public void setCreatedAt(Calendar createdAt) this.createdAt = createdAt; } Thursday, December 8, 11 }
  • 6.
  • 7.
    JAXR Java-FX JAXP JSTL StAX JME JDOM JVM JAX-RPC EJB AWT JMX Swing EAR Struts JAAS JCP JavaBean NPE Spring JAX-WS ENTERPRISE RMI JSE JNI JNDI NIO SOA JSP JSF JAXB WAR JDO JAX-RS JPQL JAF POJO EJBQL JRE JEE Thursday, December 8, 11
  • 8.
  • 9.
  • 10.
    Scala Clojure Jython JVM DynJS Rhino Groovy Thursday, December 8, 11
  • 11.
    Ruby Mais expressiva que Java class Beer attr_accessor :beer_id, :description, :created_at end Thursday, December 8, 11
  • 12.
    DRY “It is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.” - Abraham Maslow Thursday, December 8, 11
  • 13.
    JRuby Java + Ruby Thursday, December 8, 11
  • 14.
    JRuby require 'java' pdf = com.itextpdf.text.Document.new para = com.itextpdf.text.Paragraph.new 'Brought to you by JRuby' file = java.io.FileOutputStream.new 'pdf_demo.pdf' com.itextpdf.text.pdf.PdfWriter.get_instance pdf, file pdf.open pdf.add para pdf.close Thursday, December 8, 11
  • 15.
    “You get truemultithreading that can use all your computer’s cores from one process, plus a virtual machine that’s been tuned for a decade and a half.” Using JRuby - Bringing Ruby to Java Thursday, December 8, 11
  • 16.
  • 17.
    Ruby App Sinatra Rails Rack Passenger/Thin Apache/Nginx Thursday, December 8, 11
  • 18.
    Ruby App Sinatra Rails Rack Passenger/Thin Jobs Apache/Nginx crond Thursday, December 8, 11
  • 19.
    Ruby App Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/ DelayedJob Apache/Nginx crond Thursday, December 8, 11
  • 20.
    Ruby App Sinatra Rails Rack Tasks Passenger/Thin Jobs Resque/ DelayedJob Apache/Nginx crond Daemons god/monit Thursday, December 8, 11
  • 21.
    JBoss Tomcat Thursday, December 8, 11
  • 22.
    JBoss HornetQ Thursday, December 8, 11
  • 23.
    JBoss Quartz Thursday, December 8, 11
  • 24.
    JBoss Clustering Thursday, December 8, 11
  • 25.
    AS 7 Redução do footprint de memória Class loader modular Queda no tempo de startup EE6 compliant Thursday, December 8, 11
  • 26.
    TorqueBox “The power of JBoss with the expressiveness of Ruby” Jim Crossley - MagicRuby Conference Thursday, December 8, 11
  • 27.
  • 28.
    Instalação TorqueBox do zero Thursday, December 8, 11
  • 29.
    Pré-requisitos ➜ java -version java version "1.6.0_07" Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153) Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode) Thursday, December 8, 11
  • 30.
    ➜ jruby -Sgem install torquebox torquebox-capistrano-support Thursday, December 8, 11
  • 31.
    ➜ wget http://repository-torquebox.forge.cloudbees.com/ release/org/torquebox/torquebox-dist/2.0.0.beta1/torquebox- dist-2.0.0.beta1-bin.zip ➜ unzip torquebox-dist-2.0.0.beta1-bin.zip ➜ export TORQUEBOX_HOME=$PWD/torquebox- dist-2.0.0.beta1 ➜ export JBOSS_HOME=$TORQUEBOX_HOME/jboss ➜ export JRUBY_HOME=$TORQUEBOX_HOME/jruby ➜ export PATH=$JRUBY_HOME/bin:$PATH Thursday, December 8, 11
  • 32.
    Rails rails new beer -m $TORQUEBOX_HOME/share/rails/template.rb Thursday, December 8, 11
  • 33.
    Estrutura Diretórios do TorqueBox Thursday, December 8, 11
  • 34.
    Rake tasks rake torquebox:deploy rake torquebox:undeploy rake torquebox:run Thursday, December 8, 11
  • 35.
    Deployment Make knobs, not WAR! Thursday, December 8, 11
  • 36.
    beer-knob.yml application: root: /Users/Bruno/javaonebrasil/beer environment: development Thursday, December 8, 11
  • 37.
  • 38.
  • 39.
    source "http://torquebox.org/2x/builds/584/gem- repo" source 'http://rubygems.org' gem 'rails', '3.1.1' Gemfile gem 'activerecord-jdbcsqlite3-adapter' gem 'jruby-openssl' gem 'json' gem 'jquery-rails' gem "torquebox-rake-support", "2.x.incremental. 584" gem "torquebox", "2.x.incremental.584" Thursday, December 8, 11
  • 40.
    Web Rack, Sinatra, Rails Thursday, December 8, 11
  • 41.
    Caching class BeersController < ApplicationController caches_action :most_popular, :expires_in => 30.seconds def most_popular @popular_beers = Beer.most_popular(:limit => 25) end end Thursday, December 8, 11
  • 42.
  • 43.
    Clustering ➜ torquebox run --clustered Thursday, December 8, 11
  • 44.
    Internals class TorqueBoxCommand < Thor TASK_ORDER = %w(deploy undeploy start cli env help) map "run" => "start" desc "run", "Run TorqueBox" method_option :clustered, :type => :boolean, :desc => "Run TorqueBox in clustered mode" def start setup_environment TorqueBox::DeployUtils.run_server(:clustered => options.clustered, :max_threads => options['max-threads'], :bind_address => options['bind-address']) end end Thursday, December 8, 11
  • 45.
  • 46.
    mod_cluster httpd-based load balancer Thursday, December 8, 11
  • 47.
    Infinispan Caching Thursday, December 8, 11
  • 48.
    Invalidation Cache Cache Server1 Server2 Thursday, December 8, 11
  • 49.
    Invalidation Notificação Cache Cache Server1 Server2 NEW Cache Desatualizado Thursday, December 8, 11
  • 50.
    ../config/application.rb module Beer class Application < Rails::Application config.cache_store = :torque_box_store end end Thursday, December 8, 11
  • 51.
    Replicated Cache Server2 Cache Server1 Sync Cache Sync Server2 Cache Server2 Thursday, December 8, 11
  • 52.
    ../config/application.rb module Beer class Application < Rails::Application config.cache_store = :torque_box_store, {:mode => replicated, :sync =>false} end end Thursday, December 8, 11
  • 53.
    Scheduling Agendamento de Jobs Thursday, December 8, 11
  • 54.
    Internals public class RubyJobProxy implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { Ruby ruby = null; try { ruby = this.runtimePool.borrowRuntime( resolver.getComponentName() ); JobComponent job = (JobComponent)resolver.resolve( ruby ); job.run(); } catch (Exception e) { throw new JobExecutionException( e ); } finally { if (ruby != null) { this.runtimePool.returnRuntime( ruby ); } } } Thursday, December 8, 11
  • 55.
    Internals public class RubyJobProxy implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { Ruby ruby = null; try { ruby = this.runtimePool.borrowRuntime( resolver.getComponentName() ); JobComponent job = (JobComponent)resolver.resolve( ruby ); job.run(); } catch (Exception e) { throw new JobExecutionException( e ); } finally { if (ruby != null) { this.runtimePool.returnRuntime( ruby ); } } } Thursday, December 8, 11
  • 56.
    ../app/jobs class JobDemo def initialize #Codigo de inicializacao end def run # O que você quer executar end end Thursday, December 8, 11
  • 57.
    ../config/torquebox.yml jobs: sync_agenda: job: JobDemo cron: '0 0 12 * * ?' end Thursday, December 8, 11
  • 58.
    Mensageria Java Messaging Service + HornetQ Thursday, December 8, 11
  • 59.
    O Ministério daSaúde adverte: NOSQL COMO MENSAGERIA PODE TRAZER DANOS A SUA SAÚDE E A DE SEUS FAMILIARES Thursday, December 8, 11
  • 60.
    Greenfield REST + NoSQL Request/Responsext NoSQL RAILS APP pub/sub SINATRA APP Thursday, December 8, 11
  • 61.
    Real World Nobody Cares! Request/Responsext NoSQL RAILS APP pub/sub MAINFRAME Thursday, December 8, 11
  • 62.
    ../config/torquebox.yml /topics/beerTopic /queues/queueBeer: Thursday, December 8, 11
  • 63.
    Tasks class EmailerTask < TorqueBox::Messaging::Task def send_welcome(payload) to = "#{payload[:name]} <#{payload[:address]}>" # send welcome email to the user end end Thursday, December 8, 11
  • 64.
    Tasks class UserController < ApplicationController def register user = User.new(params[:user]) EmailerTask.async(:send_welcome, :address => user.email, :name => user.name) end end Thursday, December 8, 11
  • 65.
    Processors include TorqueBox::Messaging class PrintHandler < MessageProcessor   def on_message(body)     puts "Processing #{body} of #{message}"   end   def configure(opts)     @color = opts['color']   end end Thursday, December 8, 11
  • 66.
    Queues include TorqueBox req = Messaging::Queue.new '/queues/questions' res = Messaging::Queue.new '/queues/answers'   Thread.new do   req.publish "What time is it?"   puts res.receive( :timeout => 1000 ) end Thursday, December 8, 11
  • 67.
  • 68.
    Future class EmailerTask def send_welcome(payload) to = "#{payload[:name]} <#{payload[:address]}>" # long running task end end Thursday, December 8, 11
  • 69.
    Future class EmailerTask include TorqueBox::Messaging::Backgroundable always_background :send_welcome def send_welcome(payload) to = "#{payload[:name]} <#{payload[:address]}>" # long running task end end Thursday, December 8, 11
  • 70.
    Future future = @emailTask.send_welcome(:send_welcome) future.started? future.complete? future.error? future.result future.result(10000) Thursday, December 8, 11
  • 71.
  • 72.
    Services class BeerService def initialize @queue = Messaging::Queue.new(“beer”) end def start @queue.publish “Testing” end def stop # O que fazer quando o serviço receber um stop end end Thursday, December 8, 11
  • 73.
    Singleton Services Clustered Server1 Server2 BeerService BeerService Thursday, December 8, 11
  • 74.
    Singleton Services Clustered Server1 Server2 BeerService BeerService Thursday, December 8, 11
  • 75.
    Services ➜ torquebox run --clustered ../config/torquebox.yml services: BeerService: singleton: true end Thursday, December 8, 11
  • 76.
    CDI Injeção de dependências Thursday, December 8, 11
  • 77.
  • 78.
    Java package br.com.javaonebrasil; public class Beer { //gets e sets public void say(String message) { // Execução do método } } Deploy do jar na aplicação app/ models/ views/ controllers/ lib/beer.jar Thursday, December 8, 11
  • 79.
    Ruby class BeerController < ApplicationController include TorqueBox::Injectors def create beer = inject(br.com.javaonebrasil.Beer ) beer.say “Ruby is for Java” end end Thursday, December 8, 11
  • 80.
    JNDI class MyService include TorqueBox::Injectors def initialize opts={} @factory = inject("java:comp/env/jdbc/myDB") end end Thursday, December 8, 11
  • 81.
    Destinations class MyService include TorqueBox::Injectors def initialize opts={} @inbound = inject("/topic/beerpub") @outbound = inject("/queue/beer") end end Thursday, December 8, 11
  • 82.
    Transactions Queue Database Infinispan Rails Application Topic XA Distributed, multi resource transaction Thursday, December 8, 11
  • 83.
    XA (2PC) HornetQ ✔ Infinispan ✔ TorqueBox + ActiveRecord ✔ Thursday, December 8, 11
  • 84.
    Outras features Autenticação + Websockets Thursday, December 8, 11
  • 85.
  • 86.
    Stomp Box TorqueBox deployment support Thursday, December 8, 11
  • 87.
  • 88.
  • 89.
    Polyglot Immutant Queue Queue TorqueBox Thursday, December 8, 11
  • 90.
    Getting started Installing TorqueBox 2.0 http://vimeo.com/33299335 Thursday, December 8, 11
  • 91.
    Comunidade irc.freenode.net #torquebox http://torquebox.org http://github.com/torquebox twitter: @torquebox Thursday, December 8, 11
  • 92.
    Obrigado! @abstractj http://github.com/abstractj Creative Commons BY-SA 3.0 Thursday, December 8, 11