DataMapper on Infinispan
                             Clustered NoSQL
                                 Lance Ball




Thursday, September 22, 11                     1
Lance Ball

                    •Red Hat senior engineer
                    •TorqueBox core developer
                    •Perl -> C++ -> Java -> Ruby
                    •@lanceball

Thursday, September 22, 11                         2
project:odd




Thursday, September 22, 11    3
What are we talking about?


                    • DataMapper - Ruby ORM
                    • Infinispan - Java+Scala distributed cache
                    • Hibernate Search - Java ORM
                    • Lucene - Indexing and search
                    • JBoss AS7 - JEE application server
                    • TorqueBox - JRuby application server

Thursday, September 22, 11                                        4
TorqueBox




                     JRuby Application Server
                       http://torquebox.org
Thursday, September 22, 11                      5
TorqueBox

                             The Power of JBoss

                                   with the

                        Expressiveness of Ruby

Thursday, September 22, 11                        6
Thursday, September 22, 11   7
TorqueBox
                •Ruby, baby!
                •Rack apps
                •Scheduled Jobs
                •Background Tasks
                •Message Queues & Topics
                •Message Processors
                •Long-running Services
                •Distributed / Replicated Cache
Thursday, September 22, 11                        8
JRuby
                   •Healthy community
                   •Real threads
                   •Java libraries
                   •Java tools
                   •Fast runtime
                   •Better memory management**
                         ** for long running things like servers


Thursday, September 22, 11                                         9
Java
                CacheFactory.java

              public class CacheFactory {

                public CacheFactory() {
                  config = new Configuration();
                  store = new FileCacheStoreConfig();
                  store.purgeOnStartup( false );
                  config.fluent().loaders().addCacheLoader( store );
                  manager = new DefaultCacheManager( config.build() );
                }

                public Cache getCache() { return manager.getCache(); }
              }




Thursday, September 22, 11                                               10
JRuby
                cache_factory.rb

              class CacheFactory
                def initialize
                  @config = Configuration.new
                  @store = FileCacheStore.new
                  @store.purge_on_startup false
                  @config.fluent.loaders.add_cache_loader( @store )
                  @manager = DefaultCacheManager.new( @config.build )
                end

                def get_cache ; @manager.get_cache end
              end




Thursday, September 22, 11                                              11
Infinispan

                       An extremely scalable,
                       highly available data grid

                       http://www.jboss.org/infinispan



Thursday, September 22, 11                              12
Infinispan

                    •Key / Value store
                    •Highly concurrent core
                    •Data Grid
                     •Replicated
                     •Distributed
                     •Local
Thursday, September 22, 11                    13
Hotrod

                    •Binary TCP protocol
                    •Clients
                     •Java
                     •Python
                     •Ruby
                     •...
Thursday, September 22, 11                 14
NoSQL?

                    •Non-relational
                    •Scales out, not up
                    •Big data
                    •Low ceremony

Thursday, September 22, 11                15
Infinispan API
                Cache.java

                 cache.put(key, value, lifespan, timeUnit);

                 cache.putIfAbsent(key, value, lifespan, timeUnit);

                 cache.replace(key, oldVal, value, lifespan, timeUnit);

                 cache.putAsync(key, value, lifespan, timeUnit);

                 cache.keySet();

                 cache.values();

                 cache.entrySet();




Thursday, September 22, 11                                                16
Hibernate Search
                Example.java



                    import org.hibernate.search.annotations.*;

              @Indexed @ProvidedId
              public class Book {
                 @Field String title;
                 @Field String description;
                 @Field Date publicationYear;
              }




Thursday, September 22, 11                                       17
Indexing: Lucene
                Search.java


                    org.apache.lucene.search.Query luceneQuery =
                      queryBuilder.phrase()
                                    .onField( "description" )
                                    .andField( "title" )
                                    .sentence( "pat the bunny" )
                                    .createQuery();

              CacheQuery query = searchManager.getQuery( luceneQuery,
                                                         Book.class );




Thursday, September 22, 11                                               18
DataMapper

                    •Object Relational Mapper
                    •Alternative to ActiveRecord
                    •Written in Ruby
                    •http://datamapper.org

Thursday, September 22, 11                         19
Resources
                beer.rb

              class Beer
                include DataMapper::Resource
                property   :id,     Serial
                property   :name,   String
                property   :rating, Integer
                property   :notes, Text
                belongs_to :user
              end



Thursday, September 22, 11                     20
DataMapper Queries
                sample.rb


              Beer.all

              Beer.get(1)

              Beer.first( :name => 'Pisgah Pale' )

              Beer.last( :name.like => 'IPA' )

              Beer.all( :notes.like => 'hoppy' )




Thursday, September 22, 11                           21
DataMapper Adapter SPI
                sample_adapter.rb

              module DataMapper::Adapters

                class        SampleAdapter < AbstractAdapter
                  def        initialize( name, options ) ; end
                  def        create( resources ) ; end
                  def        read( query ) ; end
                  def        update( attributes, collection ) ; end
                  def        delete( collection ) ; end
                end

              end




Thursday, September 22, 11                                            22
DataMapper Filtering
                some_adapter.rb




                  def read( query )
                    records = @search_manager.search( query )
                    query.filter_records( records )
                  end




Thursday, September 22, 11                                      23
Testing
                adapter_spec.rb

              require 'dm-core/spec/shared/adapter_spec'
              describe DataMapper::Adapters::InfinispanAdapter do

                before :all do
                  @adapter = DataMapper.setup(:default,
                                              :adapter => 'infinispan')
                end

                it_should_behave_like 'An Adapter'

                describe "other important things to test" do
                  # Your tests here
                end
              end



Thursday, September 22, 11                                                24
torquebox-cache

                    • TorqueBox 2.0 gem
                    • dm-infinispan-adapter
                    • TorqueBox::Infinispan::Cache
                    • ActiveSupport::Cache::TorqueBoxStore


Thursday, September 22, 11                                   25
dm-infinispan-adapter



                       Use Infinispan as your
                       object data store



Thursday, September 22, 11                     26
dm-infinispan-adapter
               require 'dm-core'
               require 'dm-infinispan-adapter'

               class Beer
                 include DataMapper::Resource
                 property :id,     Serial
                 property :name,   String
                 property :rating, Integer
                 property :notes, Text
                 belongs_to :user
               end

               DataMapper.setup(:default,
                                :adapter=>'infinispan', :persist=>true)




Thursday, September 22, 11                                                27
But How?


Thursday, September 22, 11              28
Hibernate Search


                       Annotated Java classes




Thursday, September 22, 11                      29
Runtime Class Creation


                       How do we make Ruby’s
                       Beer.class look like an
                       annotated Java class at
                       runtime?


Thursday, September 22, 11                       30
Metaprogramming!
                dm-infinispan-adapter.rb


         require 'datamapper/model'

         module DataMapper::Adapters

           class InfinispanAdapter < AbstractAdapter

             DataMapper::Model.append_inclusions( Infinispan::Model )

           end
         end




Thursday, September 22, 11                                              31
Metaprogramming!
                datamapper/model.rb


         module Infinispan
           module Model

             def self.included(model)
               model.extend(ClassMethods)
               model.before_class_method(:finalize, :configure_index)
             end

           end
         end




Thursday, September 22, 11                                              32
Annotations
                datamapper/model.rb




        require ‘jruby/core_ext’

        annotation = {org.hibernate.search.annotations.Field => {}}
        add_method_annotation( “getName”, annotation )




Thursday, September 22, 11                                            33
Annotations
                datamapper/model.rb


        require ‘jruby/core_ext’

        annotation = {
          org.hibernate.search.annotations.Indexed => {},
          org.hibernate.search.annotations.ProvidedId => {},
          org.infinispan.marshall.SerializeWith => {"value" =>
        org.torquebox.cache.marshalling.JsonExternalizer.java_class }}

        add_class_annotation( annotation )




Thursday, September 22, 11                                               34
Become Java!



              java_class = become_java!




Thursday, September 22, 11                35
JSON Externalizer

                       Forget

                       java.io.Serializable



Thursday, September 22, 11                    36
JSON Externalizer
                JsonExternalizer.java

              public class JsonExternalizer
                  implements Externalizer<IRubyObject> {

              " @Override
              " public void writeObject(ObjectOutput output,
                                         IRubyObject object)
              " " " throws IOException {
              " " String theType = object.getType().getName();
              " " output.writeObject( theType );
              " " output.writeObject( toJSON(object) );
              " }
               }




Thursday, September 22, 11                                       37
JSON Externalizer
                JsonExternalizer.java


              public class JsonExternalizer implements
              Externalizer<IRubyObject> {

              " @Override
              " public IRubyObject readObject(ObjectInput input)
                        throws IOException, ClassNotFoundException {
              " " String theType = (String) input.readObject();
              " " String theJson = (String) input.readObject();
              " " return fromJSON(theJson, theType);"
              " }
               }




Thursday, September 22, 11                                             38
JSON Externalizer
                JsonExternalizer.java


        public class JsonExternalizer
            implements Externalizer<IRubyObject> {

            protected IRubyObject fromJSON(String json,
                                           String type)
                      throws ClassNotFoundException {

                RubyModule objectClass = runtime.getClassFromPath( type );
                return (IRubyObject) JavaEmbedUtils.invokeMethod( runtime,
                                                                  objectClass, "new",
                                                                  new Object[] { jsonHash },
                                                                  IRubyObject.class);
            }
         }




Thursday, September 22, 11                                                                     39
JSON Externalizer
                JsonExternalizer.java



        public class JsonExternalizer implements Externalizer<IRubyObject> {

            protected String toJSON(IRubyObject object) {
                return (String) JavaEmbedUtils.invokeMethod(
                                    getCurrentRuntime(), object, "to_json",
                                    EMPTY_OBJECT_ARRAY, String.class );
            }
         }




Thursday, September 22, 11                                                     40
Sequences
                dm-core/property/serial.rb




              DataMapper::Property::Serial




Thursday, September 22, 11                   41
Sequences
                dm-core/adapters/abstract_adapter.rb




              initialize_serial( resource, next_id )




Thursday, September 22, 11                             42
Sequences
                cache.rb

              module TorqueBox
                module Infinispan

                  class      Cache
                    def      increment( sequence_name, amount = 1 )
                      #      increment an integer
                    end
                    def      decrement(name, amount = 1)
                      #      decrement an integer
                    end
                  end

                end
              end



Thursday, September 22, 11                                            43
Sequences
                dm-infinispan-adapter.rb




              @metadata = Cache.new( options )

              initialize_serial( resource,
                @metadata.increment( “metadata/beers/index” ) )




Thursday, September 22, 11                                        44
Transactions
                cache_spec.rb

                describe "with JTA transactions" do

                  it "should behave like a transaction" do
                    @cache.transaction do |cache|
                      cache.put('Tommy', 'Dorsey')
                      raise "yikes!"
                      cache.put('Elvis', 'Presley')
                    end
                    @cache.get('Tommy').should be_nil
                    @cache.get('Elvis').should be_nil
                  end
                
                 end




Thursday, September 22, 11                                   45
Transactions
                dm-infinispan-adapter.rb



                  def delete( collection )
                    cache.transaction do
                      collection.each do |resource|
                        cache.remove( key(resource) )
                      end
                    end
                  end




Thursday, September 22, 11                              46
TorqueBox::Infinispan::Cache




                       Use Infinispan for...




Thursday, September 22, 11                    47
Cache
                some_file.rb



              include TorqueBox::Infinispan::Cache

              cache = Cache.new(:name => 'MyCache',
                                :mode => :replicated)

              cache.put(key, value)
              cache.get(key)




Thursday, September 22, 11                              48
ActiveSupport::Cache::TorqueBoxStore




                       Caching in Rails.

                       Replaces in-memory or
                       memcached caches.


Thursday, September 22, 11                             49
TorqueBoxStore
                config/application.rb



              module YourApp

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

              end




Thursday, September 22, 11                                 50
TorqueBoxStore
                my_app.rb

              require 'sinatra'
              require 'torquebox'

              class MyApp < Sinatra::Base

                use TorqueBox::Session::ServletStore

                get '/' do
                  session[:message] = 'Hello World!'
                  haml :index
                end

              end




Thursday, September 22, 11                             51
Beer Catalogue!




                             http://www.flickr.com/photos/burnblue/308441464/




Thursday, September 22, 11                                                     52
Model
                beer.rb
        require 'dm-core'
        require 'dm-infinispan-adapter'

        class Beer
          include DataMapper::Resource
          property :id, Serial
          property :name, String
          property :rating, Integer
          property :notes, Text
          belongs_to :user
        end

        DataMapper.setup(:default, :adapter=>'infinispan',
                                   :persist=>true)




Thursday, September 22, 11                                   53
Sinatra
                application.rb
        module BeerCatalogue
          class Application < Sinatra::Base
            get '/' do
              @beers = Beer.all( :user_id => current_user.id )
              haml :index
            end

            post '/beer' do
              Beer.create(
                :name=>params[:name], :notes=>params[:notes],
                :rating=>params[:rating], :user=>current_user)
              redirect '/'
            end
          end
        end



Thursday, September 22, 11                                       54
View
                views/index.haml
        #welcome
          Hello
          =current_user.name

        #body
          #beer-list
            %h2 Your Beers
            - if @beers.empty?
              %strong You haven't rated any beers yet. Do that now!
            %ul
              - @beers.each do |beer|
                %li
                  =beer.name
                  =beer.rating
                  =beer.notes



Thursday, September 22, 11                                            55
Source


                       http://github.com/torquebox/torquebox
                       http://github.com/torquebox/presentations




Thursday, September 22, 11                                         56
Installation
         $ gem install torquebox-server --pre 
             --source http://torquebox.org/2x/builds/LATEST/gem-repo/

         $ gem install bundler

         $ bundle install

         $ torquebox deploy .
         Deployed: beer.yml
             into: /path/to/jboss/standalone/deployments

         $ torquebox run




Thursday, September 22, 11                                              57
http://www.flickr.com/photos/crystalflickr/2317183342/




Thursday, September 22, 11                                                          58
TorqueBox 2.x

                    • Under development
                    • Continuous integration
                    • TorqueBox::Infinispan::Cache
                    • ActiveSupport::Cache::TorqueBoxStore
                    • dm-infinispan-adapter

Thursday, September 22, 11                                   59
TorqueBox 1.x


                    • Version 1.1.1 released in August
                    • Continuous integration
                    • ActiveSupport::Cache::TorqueBoxStore


Thursday, September 22, 11                                   60
Resources

                    •        http://torquebox.org/
                    •        http://github.com/torquebox
                    •        #torquebox on FreeNode
                    •        @torquebox



Thursday, September 22, 11                                 61
Questions




                             http://www.flickr.com/photos/eleaf/2536358399/




Thursday, September 22, 11                                                   62

DataMapper on Infinispan

  • 1.
    DataMapper on Infinispan Clustered NoSQL Lance Ball Thursday, September 22, 11 1
  • 2.
    Lance Ball •Red Hat senior engineer •TorqueBox core developer •Perl -> C++ -> Java -> Ruby •@lanceball Thursday, September 22, 11 2
  • 3.
  • 4.
    What are wetalking about? • DataMapper - Ruby ORM • Infinispan - Java+Scala distributed cache • Hibernate Search - Java ORM • Lucene - Indexing and search • JBoss AS7 - JEE application server • TorqueBox - JRuby application server Thursday, September 22, 11 4
  • 5.
    TorqueBox JRuby Application Server http://torquebox.org Thursday, September 22, 11 5
  • 6.
    TorqueBox The Power of JBoss with the Expressiveness of Ruby Thursday, September 22, 11 6
  • 7.
  • 8.
    TorqueBox •Ruby, baby! •Rack apps •Scheduled Jobs •Background Tasks •Message Queues & Topics •Message Processors •Long-running Services •Distributed / Replicated Cache Thursday, September 22, 11 8
  • 9.
    JRuby •Healthy community •Real threads •Java libraries •Java tools •Fast runtime •Better memory management** ** for long running things like servers Thursday, September 22, 11 9
  • 10.
    Java CacheFactory.java public class CacheFactory {   public CacheFactory() {     config = new Configuration();     store = new FileCacheStoreConfig();     store.purgeOnStartup( false );     config.fluent().loaders().addCacheLoader( store );     manager = new DefaultCacheManager( config.build() );   }   public Cache getCache() { return manager.getCache(); } } Thursday, September 22, 11 10
  • 11.
    JRuby cache_factory.rb class CacheFactory   def initialize     @config = Configuration.new     @store = FileCacheStore.new     @store.purge_on_startup false     @config.fluent.loaders.add_cache_loader( @store )     @manager = DefaultCacheManager.new( @config.build )   end   def get_cache ; @manager.get_cache end end Thursday, September 22, 11 11
  • 12.
    Infinispan An extremely scalable, highly available data grid http://www.jboss.org/infinispan Thursday, September 22, 11 12
  • 13.
    Infinispan •Key / Value store •Highly concurrent core •Data Grid •Replicated •Distributed •Local Thursday, September 22, 11 13
  • 14.
    Hotrod •Binary TCP protocol •Clients •Java •Python •Ruby •... Thursday, September 22, 11 14
  • 15.
    NoSQL? •Non-relational •Scales out, not up •Big data •Low ceremony Thursday, September 22, 11 15
  • 16.
    Infinispan API Cache.java    cache.put(key, value, lifespan, timeUnit);    cache.putIfAbsent(key, value, lifespan, timeUnit);    cache.replace(key, oldVal, value, lifespan, timeUnit);    cache.putAsync(key, value, lifespan, timeUnit);    cache.keySet();    cache.values();    cache.entrySet(); Thursday, September 22, 11 16
  • 17.
    Hibernate Search Example.java import org.hibernate.search.annotations.*; @Indexed @ProvidedId public class Book { @Field String title; @Field String description; @Field Date publicationYear; } Thursday, September 22, 11 17
  • 18.
    Indexing: Lucene Search.java org.apache.lucene.search.Query luceneQuery = queryBuilder.phrase() .onField( "description" ) .andField( "title" ) .sentence( "pat the bunny" ) .createQuery(); CacheQuery query = searchManager.getQuery( luceneQuery, Book.class ); Thursday, September 22, 11 18
  • 19.
    DataMapper •Object Relational Mapper •Alternative to ActiveRecord •Written in Ruby •http://datamapper.org Thursday, September 22, 11 19
  • 20.
    Resources beer.rb class Beer   include DataMapper::Resource   property :id, Serial   property :name, String   property :rating, Integer   property :notes, Text   belongs_to :user end Thursday, September 22, 11 20
  • 21.
    DataMapper Queries sample.rb Beer.all Beer.get(1) Beer.first( :name => 'Pisgah Pale' ) Beer.last( :name.like => 'IPA' ) Beer.all( :notes.like => 'hoppy' ) Thursday, September 22, 11 21
  • 22.
    DataMapper Adapter SPI sample_adapter.rb module DataMapper::Adapters   class SampleAdapter < AbstractAdapter     def initialize( name, options ) ; end     def create( resources ) ; end     def read( query ) ; end     def update( attributes, collection ) ; end     def delete( collection ) ; end   end end Thursday, September 22, 11 22
  • 23.
    DataMapper Filtering some_adapter.rb     def read( query ) records = @search_manager.search( query )       query.filter_records( records )     end Thursday, September 22, 11 23
  • 24.
    Testing adapter_spec.rb require 'dm-core/spec/shared/adapter_spec' describe DataMapper::Adapters::InfinispanAdapter do   before :all do     @adapter = DataMapper.setup(:default, :adapter => 'infinispan')   end   it_should_behave_like 'An Adapter'   describe "other important things to test" do # Your tests here   end end Thursday, September 22, 11 24
  • 25.
    torquebox-cache • TorqueBox 2.0 gem • dm-infinispan-adapter • TorqueBox::Infinispan::Cache • ActiveSupport::Cache::TorqueBoxStore Thursday, September 22, 11 25
  • 26.
    dm-infinispan-adapter Use Infinispan as your object data store Thursday, September 22, 11 26
  • 27.
    dm-infinispan-adapter require 'dm-core' require 'dm-infinispan-adapter' class Beer   include DataMapper::Resource   property :id, Serial   property :name, String   property :rating, Integer   property :notes, Text   belongs_to :user end DataMapper.setup(:default, :adapter=>'infinispan', :persist=>true) Thursday, September 22, 11 27
  • 28.
  • 29.
    Hibernate Search Annotated Java classes Thursday, September 22, 11 29
  • 30.
    Runtime Class Creation How do we make Ruby’s Beer.class look like an annotated Java class at runtime? Thursday, September 22, 11 30
  • 31.
    Metaprogramming! dm-infinispan-adapter.rb require 'datamapper/model' module DataMapper::Adapters   class InfinispanAdapter < AbstractAdapter     DataMapper::Model.append_inclusions( Infinispan::Model )   end end Thursday, September 22, 11 31
  • 32.
    Metaprogramming! datamapper/model.rb module Infinispan   module Model     def self.included(model)       model.extend(ClassMethods) model.before_class_method(:finalize, :configure_index)     end end end Thursday, September 22, 11 32
  • 33.
    Annotations datamapper/model.rb require ‘jruby/core_ext’ annotation = {org.hibernate.search.annotations.Field => {}} add_method_annotation( “getName”, annotation ) Thursday, September 22, 11 33
  • 34.
    Annotations datamapper/model.rb require ‘jruby/core_ext’ annotation = {   org.hibernate.search.annotations.Indexed => {},   org.hibernate.search.annotations.ProvidedId => {},   org.infinispan.marshall.SerializeWith => {"value" => org.torquebox.cache.marshalling.JsonExternalizer.java_class }} add_class_annotation( annotation ) Thursday, September 22, 11 34
  • 35.
    Become Java! java_class = become_java! Thursday, September 22, 11 35
  • 36.
    JSON Externalizer Forget java.io.Serializable Thursday, September 22, 11 36
  • 37.
    JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> { " @Override " public void writeObject(ObjectOutput output, IRubyObject object) " " " throws IOException { " " String theType = object.getType().getName(); " " output.writeObject( theType ); " " output.writeObject( toJSON(object) ); " }  } Thursday, September 22, 11 37
  • 38.
    JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> { " @Override " public IRubyObject readObject(ObjectInput input) throws IOException, ClassNotFoundException { " " String theType = (String) input.readObject(); " " String theJson = (String) input.readObject(); " " return fromJSON(theJson, theType);" " }  } Thursday, September 22, 11 38
  • 39.
    JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> {     protected IRubyObject fromJSON(String json, String type) throws ClassNotFoundException {         RubyModule objectClass = runtime.getClassFromPath( type );         return (IRubyObject) JavaEmbedUtils.invokeMethod( runtime, objectClass, "new", new Object[] { jsonHash }, IRubyObject.class);     }  } Thursday, September 22, 11 39
  • 40.
    JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> {     protected String toJSON(IRubyObject object) {         return (String) JavaEmbedUtils.invokeMethod( getCurrentRuntime(), object, "to_json", EMPTY_OBJECT_ARRAY, String.class );     }  } Thursday, September 22, 11 40
  • 41.
    Sequences dm-core/property/serial.rb DataMapper::Property::Serial Thursday, September 22, 11 41
  • 42.
    Sequences dm-core/adapters/abstract_adapter.rb initialize_serial( resource, next_id ) Thursday, September 22, 11 42
  • 43.
    Sequences cache.rb module TorqueBox   module Infinispan     class Cache       def increment( sequence_name, amount = 1 ) # increment an integer       end       def decrement(name, amount = 1) # decrement an integer       end     end   end end Thursday, September 22, 11 43
  • 44.
    Sequences dm-infinispan-adapter.rb @metadata = Cache.new( options ) initialize_serial( resource, @metadata.increment( “metadata/beers/index” ) ) Thursday, September 22, 11 44
  • 45.
    Transactions cache_spec.rb   describe "with JTA transactions" do     it "should behave like a transaction" do       @cache.transaction do |cache|         cache.put('Tommy', 'Dorsey')         raise "yikes!"         cache.put('Elvis', 'Presley')       end       @cache.get('Tommy').should be_nil       @cache.get('Elvis').should be_nil     end    end Thursday, September 22, 11 45
  • 46.
    Transactions dm-infinispan-adapter.rb     def delete( collection )       cache.transaction do         collection.each do |resource|           cache.remove( key(resource) )         end       end     end Thursday, September 22, 11 46
  • 47.
    TorqueBox::Infinispan::Cache Use Infinispan for... Thursday, September 22, 11 47
  • 48.
    Cache some_file.rb include TorqueBox::Infinispan::Cache cache = Cache.new(:name => 'MyCache', :mode => :replicated) cache.put(key, value) cache.get(key) Thursday, September 22, 11 48
  • 49.
    ActiveSupport::Cache::TorqueBoxStore Caching in Rails. Replaces in-memory or memcached caches. Thursday, September 22, 11 49
  • 50.
    TorqueBoxStore config/application.rb module YourApp   class Application < Rails::Application     config.cache_store = :torque_box_store end end Thursday, September 22, 11 50
  • 51.
    TorqueBoxStore my_app.rb require 'sinatra' require 'torquebox' class MyApp < Sinatra::Base   use TorqueBox::Session::ServletStore   get '/' do     session[:message] = 'Hello World!'     haml :index   end end Thursday, September 22, 11 51
  • 52.
    Beer Catalogue! http://www.flickr.com/photos/burnblue/308441464/ Thursday, September 22, 11 52
  • 53.
    Model beer.rb require 'dm-core' require 'dm-infinispan-adapter' class Beer   include DataMapper::Resource   property :id, Serial   property :name, String   property :rating, Integer   property :notes, Text   belongs_to :user end DataMapper.setup(:default, :adapter=>'infinispan', :persist=>true) Thursday, September 22, 11 53
  • 54.
    Sinatra application.rb module BeerCatalogue   class Application < Sinatra::Base     get '/' do       @beers = Beer.all( :user_id => current_user.id )       haml :index     end     post '/beer' do       Beer.create( :name=>params[:name], :notes=>params[:notes], :rating=>params[:rating], :user=>current_user)       redirect '/'     end   end end Thursday, September 22, 11 54
  • 55.
    View views/index.haml #welcome   Hello   =current_user.name #body   #beer-list     %h2 Your Beers     - if @beers.empty?       %strong You haven't rated any beers yet. Do that now!     %ul       - @beers.each do |beer|         %li           =beer.name           =beer.rating =beer.notes Thursday, September 22, 11 55
  • 56.
    Source http://github.com/torquebox/torquebox http://github.com/torquebox/presentations Thursday, September 22, 11 56
  • 57.
    Installation $ gem install torquebox-server --pre --source http://torquebox.org/2x/builds/LATEST/gem-repo/ $ gem install bundler $ bundle install $ torquebox deploy . Deployed: beer.yml into: /path/to/jboss/standalone/deployments $ torquebox run Thursday, September 22, 11 57
  • 58.
  • 59.
    TorqueBox 2.x • Under development • Continuous integration • TorqueBox::Infinispan::Cache • ActiveSupport::Cache::TorqueBoxStore • dm-infinispan-adapter Thursday, September 22, 11 59
  • 60.
    TorqueBox 1.x • Version 1.1.1 released in August • Continuous integration • ActiveSupport::Cache::TorqueBoxStore Thursday, September 22, 11 60
  • 61.
    Resources • http://torquebox.org/ • http://github.com/torquebox • #torquebox on FreeNode • @torquebox Thursday, September 22, 11 61
  • 62.
    Questions http://www.flickr.com/photos/eleaf/2536358399/ Thursday, September 22, 11 62