SlideShare uma empresa Scribd logo
1 de 43
Baixar para ler offline
STANDING ON
                    THE SHOULDERS
                      OF GIANTS
                      WITH JRUBY


måndag 19 mars 12
Theo
                    @iconara
måndag 19 mars 12
Chief Architect at




måndag 19 mars 12
måndag 19 mars 12
ruby




måndag 19 mars 12
TL;DR
              Most of you are Java developers
              Writing Java is tedious
              There’s truckloads of great Java libraries
              The JVM is awesome
              Ruby is awesome
              ∴ JRuby FTW

måndag 19 mars 12
just


                     I’M NOT HERE TO
                    MAKE FUN OF JAVA



måndag 19 mars 12
JRuby vs. vanilla Ruby
              Real threads
              A working GC
              Every Java, Scala and Ruby library ever made
              All the JVM awesomeness, JIT, the lot




måndag 19 mars 12
JRuby vs. Java
              It doesn’t make you want to stab yourself




måndag 19 mars 12
måndag 19 mars 12
JRUBY ♥ JAVA
                    A WHIRLWIND TOUR



måndag 19 mars 12
JRuby ♥ Java
              stuff = TreeMap.new
              stuff['windmill'] = 'rocket'
              stuff['pirate'] = 'bees'
              stuff.each do |something|
                # redacted
              end




måndag 19 mars 12
JRuby ♥ Java
              require 'java'
              require 'rabbitmq-client.jar'

              import 'com.rabbitmq.client.ConnectionFactory'

              factory = ConnectionFactory.new()
              factory.setUri('amqp://localhost:5672/')
              connection = factory.newConnection()




måndag 19 mars 12
JRuby ♥ Java
              require 'java'
              require 'rabbitmq-client.jar'

              import 'com.rabbitmq.client.ConnectionFactory'

              factory = ConnectionFactory.new
              factory.uri = 'amqp://localhost:5672/'
              connection = factory.new_connection




måndag 19 mars 12
JRuby ♥ Java
              class Worker < Thread
                def run
                  puts 'Hard work, no play'
                end
              end

              # or

              class Worker
                include Runnable

                def run
                  puts 'Hard work, no play'
                end
              end




måndag 19 mars 12
JRuby ♥ Java
              pool = Executors.new_fixed_thread_pool(3)

              memes = LinkedBlockingQueue.new

              10.times do
                pool.submit do
                  open('http://api.autome.me/text').read.each_line do |meme|
                    memes << meme
                  end
                end
              end

              pool.shutdown
              pool.await_termination(3, TimeUnit::DAYS)

              memes.each { |m| puts(m) }




måndag 19 mars 12
JRUBY FOR
                    REPRESSED JAVA
                     DEVELOPERS


måndag 19 mars 12
Made up fact
              84% of Java devs don’t write tests because it’s
              way too much extra code to type.




måndag 19 mars 12
Testing
              public class Person {
                public final String firstName;
                public final String lastName;

                    public Person(String firstName, String lastName) {
                      this.firstName = firstName;
                      this.lastName = lastName;
                    }

                    public String getFullName() {
                      return String.format("%s %s", firstName, lastName);
                    }

                    // omg I’m already bored
              }




måndag 19 mars 12
Testing
              class TestPerson < Test::Unit::TestCase
                def setup
                  @person = Person.new('James', 'Gosling')
                end

                def test_full_name
                  assert_equal('James Gosling', @person.full_name)
                end
              end

              # this is TestUnit, it’s part of the stdlib




måndag 19 mars 12
Testing
              describe Person do
                describe '#full_name' do
                  before do
                    @person = Person.new('James', 'Gosling')
                  end

                  it 'is the first name and the last name with a space in-between' do
                    @person.full_name.should == 'James Gosling'
                  end
                end
              end

              # this is RSpec, read more at rspec.info




måndag 19 mars 12
Made up fact
              Ant was designed by the same people who
              came up with the QWERTY layout.




måndag 19 mars 12
Automation
               <?xml version="1.0"?>
               <project name="MyProject" default="dist" basedir=".">
                   <description>
                       simple example build file
                   </description>
                   <!-- set global properties for this build -->
                   <property name="src" location="src"/>
                   <property name="build" location="build"/>
                   <property name="dist" location="dist"/>
                   <target name="init">
                       <!-- Create the time stamp -->
                       <tstamp/>
                       <!-- Create the build directory structure used by compile -->
                       <mkdir dir="${build}"/>
                   </target>
                   <target name="compile" depends="init" description="compile the source ">
                       <!-- Compile the java code from ${src} into ${build} -->
                       <javac srcdir="${src}" destdir="${build}"/>
                   </target>
                   <target name="dist" depends="compile" description="generate the distribution">
                       <!-- Create the distribution directory -->
                       <mkdir dir="${dist}/lib"/>
                       <!-- And don’t get me started on Maven, $%&@*! -->
                       <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
måndag 19 mars 12
Automation
           require 'ant'

           src_dir = 'src'
           build_dir = 'build'
           dist_dir = 'dist'
           timestamp = Time.now

           task :init do
             mkdir_p build_dir
           end

           task :compile => :init do
             ant.javac :srcdir => src_dir, :destdir => build_dir
           end

           task :dist => :compile do
             mkdir_p "#{dist_dir}/lib"
             ant.jar :jarfile => "#{dist_dir}/lib/MyProject-#{timestamp}.jar",
                     :basedir => build_dir
           end

               task :clean do
                  rm_rf build_dir
                  rm_rf dist_dir
måndag 19 mars 12
Made up fact
              The average number of lines in a Java web
              application is somewhere around 100 000




måndag 19 mars 12
Don’t make it so hard
              get '/' do
                erb :index
              end

              post '/register' do
                stuff.save(params[:name], params[:email], params[:shoe_size])
                redirect '/thanks'
              end

              get '/thanks' do
                @name = params[:name]
                erb :thanks
              end

              # this is Sinatra, read more at sinatrarb.com




måndag 19 mars 12
Pack it up in a
              WAR and ship it
              $ warbler war

              # warbler can be found at github.com/jruby/warbler
              # also check out torquebox.org, and github.com/trinidad/trinidad




måndag 19 mars 12
Make a console
              $ hbase shell

              HBase Shell; enter 'help<RETURN>' for list of supported commands.
              Type "exit<RETURN>" to leave the HBase Shell
              Version 0.90.4-cdh3u2, r, Thu Oct 13 20:32:26 PDT 2011

              hbase(main):001:0>   create 'test', 'cf'
              0 row(s) in 1.2200   seconds
              hbase(main):002:0>   put 'test', 'row1', 'cf:a', 'value1'
              0 row(s) in 0.0560   seconds
              hbase(main):003:0>   put 'test', 'row2', 'cf:b', 'value2'
              0 row(s) in 0.0370   seconds




måndag 19 mars 12
Monitoring
              require 'jmx'

              client = JMX.connect(:port => 7199)

              storage_service = client['org.apache.cassandra.db:type=StorageService']
              storage_service.keyspaces.each do |keyspace|
                puts keyspace
              end

              memory_mbean = client['java.lang:type=Memory']
              puts memory_mbean.heap_memory_usage.used

              memory_mbean.gc




måndag 19 mars 12
Configuration
              conf = configuration do
                base_keys :api_key, :date

                    dimension   :path
                    dimension   :section
                    dimension   :country
                    dimension   :section, :country

                metric :pageviews
                metric :reach, :user_id, :type => :unique
                metric :clicks, :click?, :type => :predicate
              end

              counters = conf.build!




måndag 19 mars 12
SNEAK SOME RUBY INTO THAT
                      ENTERPRISE APPLICATION



måndag 19 mars 12
STANDING ON
                    THE SHOULDERS
                      OF GIANTS
                      WITH JRUBY


måndag 19 mars 12
LET’S STACK SOME
                     ABSTRACTIONS ON
                    TOP OF THEM THERE
                      ABSTRACTIONS


måndag 19 mars 12
Our stack: RabbitMQ
              We use the Java driver, with a JRuby interface
              we call HotBunnies
              github.com/ruby-amqp/hot_bunnies




måndag 19 mars 12
Our stack: RabbitMQ
              require 'hot_bunnies'

              connection = HotBunnies.connect(:host => 'localhost')
              channel = connection.create_channel
              queue = channel.queue('test_queue')
              queue.bind('test_exch', :routing_key => 'hi')

              subscription = queue.subscribe(:ack => true, :blocking => false) do |headers, msg|
                # do awesome stuff
              end




måndag 19 mars 12
Our stack: MongoDB
              Go listen to David’s talk tomorrow
              We use the Ruby driver, because we wouldn’t
              get anything done otherwise




måndag 19 mars 12
Our stack: MongoDB
              BasicDBObject doc = new BasicDBObject();
              doc.put("name", "MongoDB");
              doc.put("type", "database");
              doc.put("count", 1);

              BasicDBObject info = new BasicDBObject();
              info.put("x", 203);
              info.put("y", 102);

              doc.put("info", info);

              coll.insert(doc);

              vs.

              coll.insert(
                'name' => 'MongoDB',
                'type' => 'database',
                'count' => 1,
                'info' => {'x' => 203, 'y' => 102}
              )


måndag 19 mars 12
Our stack: Cassandra
              We use a JRuby wrapper on top of Pelops
              github.com/iconara/eurydice




måndag 19 mars 12
Our stack: Cassandra
              Mutator mutator = Pelops.createMutator(pool);
              Column nameColumn = mutator.newColumn("name", "Dan");
              Column ageColumn = mutator.newColumn("age", Bytes.fromInt(33));
              List<Column> columns = mutator.newColumnList(nameColumn, ageColumn);
              mutator.writeColumns(columnFamily, rowKey, columns);
              mutator.execute(ConsistencyLevel.ONE);



              vs.



              columns = {'name' => 'Dan', 'age' => 33}
              column_family.update(row_key, columns, :consistency_level => :one)




måndag 19 mars 12
Our stack: Akka
              Scala is nice, but we’ve got better things to do
              than to wait for code to compile
              Akka is awesome, so we created Mikka
              github.com/iconara/mikka




måndag 19 mars 12
Our stack: Akka
              class Ping < Mikka::Actor
                def pre_start
                  @pong = context.actor_of(Pong)
                  @pong << :ping
                end

                def receive(message)
                  context.reply(:ping)
                end
              end

              class Pong < Mikka::Actor
                def receive(message)
                  context.reply(:pong)
                end
              end

              ping = Mikka.actor_of(Ping).start




måndag 19 mars 12
Our stack: numbers
              We process hundreds of millions of messages
              per day, using less than 20K lines of JRuby




måndag 19 mars 12
twitter.com/iconara
                    architecturalatrocities.com
                           burtcorp.com



måndag 19 mars 12

Mais conteúdo relacionado

Mais procurados

Rails' Next Top Model
Rails' Next Top ModelRails' Next Top Model
Rails' Next Top Model
Adam Keys
 
13 java beans
13 java beans13 java beans
13 java beans
snopteck
 

Mais procurados (10)

Rails' Next Top Model
Rails' Next Top ModelRails' Next Top Model
Rails' Next Top Model
 
Spring 3.0 dependancy injection
Spring 3.0 dependancy injectionSpring 3.0 dependancy injection
Spring 3.0 dependancy injection
 
Brubeck: Overview
Brubeck: OverviewBrubeck: Overview
Brubeck: Overview
 
Building Reusable Puppet Modules
Building Reusable Puppet ModulesBuilding Reusable Puppet Modules
Building Reusable Puppet Modules
 
MySQL Proxy tutorial
MySQL Proxy tutorialMySQL Proxy tutorial
MySQL Proxy tutorial
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
Rapid web development, the right way.
Rapid web development, the right way.Rapid web development, the right way.
Rapid web development, the right way.
 
Cassandra data modeling talk
Cassandra data modeling talkCassandra data modeling talk
Cassandra data modeling talk
 
13 java beans
13 java beans13 java beans
13 java beans
 
Groovy, Transforming Language
Groovy, Transforming LanguageGroovy, Transforming Language
Groovy, Transforming Language
 

Destaque (7)

Evaluation question 2
Evaluation question 2Evaluation question 2
Evaluation question 2
 
Karl murdock POL
Karl murdock POLKarl murdock POL
Karl murdock POL
 
La republic dominicana
La republic dominicanaLa republic dominicana
La republic dominicana
 
Chasing the elephant
Chasing the elephantChasing the elephant
Chasing the elephant
 
Learning to build distributed systems the hard way
Learning to build distributed systems the hard wayLearning to build distributed systems the hard way
Learning to build distributed systems the hard way
 
Oplag3
Oplag3Oplag3
Oplag3
 
Shortcuts around the mistakes I've made scaling MongoDB
Shortcuts around the mistakes I've made scaling MongoDB Shortcuts around the mistakes I've made scaling MongoDB
Shortcuts around the mistakes I've made scaling MongoDB
 

Semelhante a Standing on the shoulders of giants with JRuby

HOW TO BUILD GEMS #shibuyarb
HOW TO BUILD GEMS #shibuyarbHOW TO BUILD GEMS #shibuyarb
HOW TO BUILD GEMS #shibuyarb
SATOSHI TAGOMORI
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
Kyle Oba
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 
Lunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and CapybaraLunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and Capybara
Marc Seeger
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
Clinton Dreisbach
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-Tuesday
Eddie Kao
 

Semelhante a Standing on the shoulders of giants with JRuby (20)

HOW TO BUILD GEMS #shibuyarb
HOW TO BUILD GEMS #shibuyarbHOW TO BUILD GEMS #shibuyarb
HOW TO BUILD GEMS #shibuyarb
 
A jar-nORM-ous Task
A jar-nORM-ous TaskA jar-nORM-ous Task
A jar-nORM-ous Task
 
When Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of TorqueboxWhen Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of Torquebox
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
Gem That (2009)
Gem That (2009)Gem That (2009)
Gem That (2009)
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
Rails Intro & Tutorial
Rails Intro & TutorialRails Intro & Tutorial
Rails Intro & Tutorial
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 
Lunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and CapybaraLunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and Capybara
 
Una historia de ds ls en ruby
Una historia de ds ls en rubyUna historia de ds ls en ruby
Una historia de ds ls en ruby
 
Use Your MySQL Knowledge to Become a MongoDB Guru
Use Your MySQL Knowledge to Become a MongoDB GuruUse Your MySQL Knowledge to Become a MongoDB Guru
Use Your MySQL Knowledge to Become a MongoDB Guru
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-Tuesday
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
 
Workflow para desenvolvimento Web & Mobile usando grunt.js
Workflow para desenvolvimento Web & Mobile usando grunt.jsWorkflow para desenvolvimento Web & Mobile usando grunt.js
Workflow para desenvolvimento Web & Mobile usando grunt.js
 

Mais de Theo Hultberg

Mais de Theo Hultberg (7)

AWS Cost Optimization
AWS Cost OptimizationAWS Cost Optimization
AWS Cost Optimization
 
Cassandra for all the Things
Cassandra for all the ThingsCassandra for all the Things
Cassandra for all the Things
 
Building a CQL driver
Building a CQL driverBuilding a CQL driver
Building a CQL driver
 
Learning to build distributed systems the hard way
Learning to build distributed systems the hard wayLearning to build distributed systems the hard way
Learning to build distributed systems the hard way
 
Learning to Build Distributed Systems the Hard Way
Learning to Build Distributed Systems the Hard WayLearning to Build Distributed Systems the Hard Way
Learning to Build Distributed Systems the Hard Way
 
A Guide to the Post Relational Revolution
A Guide to the Post Relational RevolutionA Guide to the Post Relational Revolution
A Guide to the Post Relational Revolution
 
Concurrency and Distributed Systems Using JRuby
Concurrency and Distributed Systems Using JRubyConcurrency and Distributed Systems Using JRuby
Concurrency and Distributed Systems Using JRuby
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Último (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 

Standing on the shoulders of giants with JRuby

  • 1. STANDING ON THE SHOULDERS OF GIANTS WITH JRUBY måndag 19 mars 12
  • 2. Theo @iconara måndag 19 mars 12
  • 6. TL;DR Most of you are Java developers Writing Java is tedious There’s truckloads of great Java libraries The JVM is awesome Ruby is awesome ∴ JRuby FTW måndag 19 mars 12
  • 7. just I’M NOT HERE TO MAKE FUN OF JAVA måndag 19 mars 12
  • 8. JRuby vs. vanilla Ruby Real threads A working GC Every Java, Scala and Ruby library ever made All the JVM awesomeness, JIT, the lot måndag 19 mars 12
  • 9. JRuby vs. Java It doesn’t make you want to stab yourself måndag 19 mars 12
  • 11. JRUBY ♥ JAVA A WHIRLWIND TOUR måndag 19 mars 12
  • 12. JRuby ♥ Java stuff = TreeMap.new stuff['windmill'] = 'rocket' stuff['pirate'] = 'bees' stuff.each do |something| # redacted end måndag 19 mars 12
  • 13. JRuby ♥ Java require 'java' require 'rabbitmq-client.jar' import 'com.rabbitmq.client.ConnectionFactory' factory = ConnectionFactory.new() factory.setUri('amqp://localhost:5672/') connection = factory.newConnection() måndag 19 mars 12
  • 14. JRuby ♥ Java require 'java' require 'rabbitmq-client.jar' import 'com.rabbitmq.client.ConnectionFactory' factory = ConnectionFactory.new factory.uri = 'amqp://localhost:5672/' connection = factory.new_connection måndag 19 mars 12
  • 15. JRuby ♥ Java class Worker < Thread def run puts 'Hard work, no play' end end # or class Worker include Runnable def run puts 'Hard work, no play' end end måndag 19 mars 12
  • 16. JRuby ♥ Java pool = Executors.new_fixed_thread_pool(3) memes = LinkedBlockingQueue.new 10.times do pool.submit do open('http://api.autome.me/text').read.each_line do |meme| memes << meme end end end pool.shutdown pool.await_termination(3, TimeUnit::DAYS) memes.each { |m| puts(m) } måndag 19 mars 12
  • 17. JRUBY FOR REPRESSED JAVA DEVELOPERS måndag 19 mars 12
  • 18. Made up fact 84% of Java devs don’t write tests because it’s way too much extra code to type. måndag 19 mars 12
  • 19. Testing public class Person { public final String firstName; public final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFullName() { return String.format("%s %s", firstName, lastName); } // omg I’m already bored } måndag 19 mars 12
  • 20. Testing class TestPerson < Test::Unit::TestCase def setup @person = Person.new('James', 'Gosling') end def test_full_name assert_equal('James Gosling', @person.full_name) end end # this is TestUnit, it’s part of the stdlib måndag 19 mars 12
  • 21. Testing describe Person do describe '#full_name' do before do @person = Person.new('James', 'Gosling') end it 'is the first name and the last name with a space in-between' do @person.full_name.should == 'James Gosling' end end end # this is RSpec, read more at rspec.info måndag 19 mars 12
  • 22. Made up fact Ant was designed by the same people who came up with the QWERTY layout. måndag 19 mars 12
  • 23. Automation <?xml version="1.0"?> <project name="MyProject" default="dist" basedir="."> <description> simple example build file </description> <!-- set global properties for this build --> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <!-- Create the time stamp --> <tstamp/> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target> <target name="compile" depends="init" description="compile the source "> <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile" description="generate the distribution"> <!-- Create the distribution directory --> <mkdir dir="${dist}/lib"/> <!-- And don’t get me started on Maven, $%&@*! --> <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --> måndag 19 mars 12
  • 24. Automation require 'ant' src_dir = 'src' build_dir = 'build' dist_dir = 'dist' timestamp = Time.now task :init do mkdir_p build_dir end task :compile => :init do ant.javac :srcdir => src_dir, :destdir => build_dir end task :dist => :compile do mkdir_p "#{dist_dir}/lib" ant.jar :jarfile => "#{dist_dir}/lib/MyProject-#{timestamp}.jar", :basedir => build_dir end task :clean do rm_rf build_dir rm_rf dist_dir måndag 19 mars 12
  • 25. Made up fact The average number of lines in a Java web application is somewhere around 100 000 måndag 19 mars 12
  • 26. Don’t make it so hard get '/' do erb :index end post '/register' do stuff.save(params[:name], params[:email], params[:shoe_size]) redirect '/thanks' end get '/thanks' do @name = params[:name] erb :thanks end # this is Sinatra, read more at sinatrarb.com måndag 19 mars 12
  • 27. Pack it up in a WAR and ship it $ warbler war # warbler can be found at github.com/jruby/warbler # also check out torquebox.org, and github.com/trinidad/trinidad måndag 19 mars 12
  • 28. Make a console $ hbase shell HBase Shell; enter 'help<RETURN>' for list of supported commands. Type "exit<RETURN>" to leave the HBase Shell Version 0.90.4-cdh3u2, r, Thu Oct 13 20:32:26 PDT 2011 hbase(main):001:0> create 'test', 'cf' 0 row(s) in 1.2200 seconds hbase(main):002:0> put 'test', 'row1', 'cf:a', 'value1' 0 row(s) in 0.0560 seconds hbase(main):003:0> put 'test', 'row2', 'cf:b', 'value2' 0 row(s) in 0.0370 seconds måndag 19 mars 12
  • 29. Monitoring require 'jmx' client = JMX.connect(:port => 7199) storage_service = client['org.apache.cassandra.db:type=StorageService'] storage_service.keyspaces.each do |keyspace| puts keyspace end memory_mbean = client['java.lang:type=Memory'] puts memory_mbean.heap_memory_usage.used memory_mbean.gc måndag 19 mars 12
  • 30. Configuration conf = configuration do base_keys :api_key, :date dimension :path dimension :section dimension :country dimension :section, :country metric :pageviews metric :reach, :user_id, :type => :unique metric :clicks, :click?, :type => :predicate end counters = conf.build! måndag 19 mars 12
  • 31. SNEAK SOME RUBY INTO THAT ENTERPRISE APPLICATION måndag 19 mars 12
  • 32. STANDING ON THE SHOULDERS OF GIANTS WITH JRUBY måndag 19 mars 12
  • 33. LET’S STACK SOME ABSTRACTIONS ON TOP OF THEM THERE ABSTRACTIONS måndag 19 mars 12
  • 34. Our stack: RabbitMQ We use the Java driver, with a JRuby interface we call HotBunnies github.com/ruby-amqp/hot_bunnies måndag 19 mars 12
  • 35. Our stack: RabbitMQ require 'hot_bunnies' connection = HotBunnies.connect(:host => 'localhost') channel = connection.create_channel queue = channel.queue('test_queue') queue.bind('test_exch', :routing_key => 'hi') subscription = queue.subscribe(:ack => true, :blocking => false) do |headers, msg| # do awesome stuff end måndag 19 mars 12
  • 36. Our stack: MongoDB Go listen to David’s talk tomorrow We use the Ruby driver, because we wouldn’t get anything done otherwise måndag 19 mars 12
  • 37. Our stack: MongoDB BasicDBObject doc = new BasicDBObject(); doc.put("name", "MongoDB"); doc.put("type", "database"); doc.put("count", 1); BasicDBObject info = new BasicDBObject(); info.put("x", 203); info.put("y", 102); doc.put("info", info); coll.insert(doc); vs. coll.insert( 'name' => 'MongoDB', 'type' => 'database', 'count' => 1, 'info' => {'x' => 203, 'y' => 102} ) måndag 19 mars 12
  • 38. Our stack: Cassandra We use a JRuby wrapper on top of Pelops github.com/iconara/eurydice måndag 19 mars 12
  • 39. Our stack: Cassandra Mutator mutator = Pelops.createMutator(pool); Column nameColumn = mutator.newColumn("name", "Dan"); Column ageColumn = mutator.newColumn("age", Bytes.fromInt(33)); List<Column> columns = mutator.newColumnList(nameColumn, ageColumn); mutator.writeColumns(columnFamily, rowKey, columns); mutator.execute(ConsistencyLevel.ONE); vs. columns = {'name' => 'Dan', 'age' => 33} column_family.update(row_key, columns, :consistency_level => :one) måndag 19 mars 12
  • 40. Our stack: Akka Scala is nice, but we’ve got better things to do than to wait for code to compile Akka is awesome, so we created Mikka github.com/iconara/mikka måndag 19 mars 12
  • 41. Our stack: Akka class Ping < Mikka::Actor def pre_start @pong = context.actor_of(Pong) @pong << :ping end def receive(message) context.reply(:ping) end end class Pong < Mikka::Actor def receive(message) context.reply(:pong) end end ping = Mikka.actor_of(Ping).start måndag 19 mars 12
  • 42. Our stack: numbers We process hundreds of millions of messages per day, using less than 20K lines of JRuby måndag 19 mars 12
  • 43. twitter.com/iconara architecturalatrocities.com burtcorp.com måndag 19 mars 12