Your SlideShare is downloading. ×
Standing on the shoulders of giants with JRuby
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

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

Standing on the shoulders of giants with JRuby

2,827
views

Published on

Presentation held at Software Passion Summit 2012

Presentation held at Software Passion Summit 2012

Published in: Technology, News & Politics

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,827
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
7
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. STANDING ON THE SHOULDERS OF GIANTS WITH JRUBYmåndag 19 mars 12
  • 2. Theo @iconaramåndag 19 mars 12
  • 3. Chief Architect atmåndag 19 mars 12
  • 4. måndag 19 mars 12
  • 5. rubymå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 FTWmåndag 19 mars 12
  • 7. just I’M NOT HERE TO MAKE FUN OF JAVAmå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 lotmåndag 19 mars 12
  • 9. JRuby vs. Java It doesn’t make you want to stab yourselfmåndag 19 mars 12
  • 10. måndag 19 mars 12
  • 11. JRUBY ♥ JAVA A WHIRLWIND TOURmåndag 19 mars 12
  • 12. JRuby ♥ Java stuff = TreeMap.new stuff[windmill] = rocket stuff[pirate] = bees stuff.each do |something| # redacted endmå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_connectionmå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 endmå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 DEVELOPERSmå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 stdlibmå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.infomå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_dirmåndag 19 mars 12
  • 25. Made up fact The average number of lines in a Java web application is somewhere around 100 000må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.commå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/trinidadmå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 secondsmå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.gcmå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 APPLICATIONmåndag 19 mars 12
  • 32. STANDING ON THE SHOULDERS OF GIANTS WITH JRUBYmåndag 19 mars 12
  • 33. LET’S STACK SOME ABSTRACTIONS ON TOP OF THEM THERE ABSTRACTIONSmå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_bunniesmå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 endmå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 otherwisemå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/eurydicemå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/mikkamå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).startmåndag 19 mars 12
  • 42. Our stack: numbers We process hundreds of millions of messages per day, using less than 20K lines of JRubymåndag 19 mars 12
  • 43. twitter.com/iconara architecturalatrocities.com burtcorp.commåndag 19 mars 12

×