Your SlideShare is downloading. ×
Oscon 2010
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

Oscon 2010

3,016

Published on

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

No Downloads
Views
Total Views
3,016
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
28
Comments
0
Likes
10
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. Saturday, July 24, 2010
  • 2. Ruby on Mirah on App Engine Run your apps on Google Servers, with access to first-class Java APIs John Woodell Charles Nutter July 22, 2010 2 Saturday, July 24, 2010
  • 3. Google App Engine 3 Saturday, July 24, 2010
  • 4. Key Features • No need to install or maintain your own stack • Use Google scalable services via standard APIs • Built-in application management console • Pay-as-you-go, with free quota to get started 4 Saturday, July 24, 2010
  • 5. Key Limitations • No native code • No threads or sockets • No writing to the filesystem • No more than 30 seconds per request 5 Saturday, July 24, 2010
  • 6. Dev AppServer • Local implementation of services – LRU memcache – Disk-backed datastore – HttpClient-backed URLFetch • Emulates the production environment – Sandbox restrictions may be inconsistent, so run tests on production servers as well 6 Saturday, July 24, 2010
  • 7. Deployment • Your app lives at – <app_id>.appspot.com, or – Custom domain with Google Apps • Deploying uploads – Static files – Resource files – Other metadata (datastore indexes, cron jobs) • Admin Console – dashboards – manage multiple versions – view logs 7 Saturday, July 24, 2010
  • 8. Quotas and Billing Resource Provided Free Additional Cost CPU time 6.5 hours/day $0.10/hour Bandwidth In 1GByte/day $0.10/GByte Bandwidth Out 1GByte/day $0.12/GByte Stored Data 1 GB $0.005/GB-day Emails sent 2000/day to users $0.0001/email 50000/day to admins 8 Saturday, July 24, 2010
  • 9. App Engine Product Roadmap • SSL for third-party domains • Background servers capable of running for longer than 30s • Ability to reserve instances to reduce application loading overhead • Ability to select different availability vs. latency options for Datastore • Support for mapping operations across datasets • Datastore dump and restore facility • Raise request/response size limits for some APIs • Improved monitoring and alerting of application serving • Support for Browser Push (Comet) communication • Built-in support for OAuth & OpenID 9 Saturday, July 24, 2010
  • 10. JRuby on App Engine 10 Saturday, July 24, 2010
  • 11. Benefits of JRuby • Outperforms MRI in many cases... 2x to 10x • Gem extensions written in Java (no more segfaults) • A wealth of integration options and first-class Java APIs • Spin-up new instances quickly using Mirah/Java servlets 11 Saturday, July 24, 2010
  • 12. App Engine JRuby Milestones • 2009-04-08 @olabini publishes blog post on YARBL • 2009-04-09 @nicksieger publishes warbler demo • 2009-05-06 RailsConf (sinatra & merb) • 2009-11-02 0.0.5 bundler, precompilation & Duby preview • 2009-11-20 RubyConf (Rails 3.0.pre & Duby App) • 2009-12-27 @urekat publishes Rails 2.3.5 patches • 2010-01-11 @codingforrent published rails/dm gem • 2010-01-21 0.0.8 Rails 2.3.5 Primer for DM & TinyDS • 2010-01-26 0.0.9 Mechanize and Hpricot demos • 2010-02-27 0.0.10 ActionMailer, ImageService, jruby-openssl • 2010-04-08 @azazeal blog post on taxster.gr (OpenID) • 2010-06-09 0.0.14 JRuby 1.5.1 & app.yaml preview 12 Saturday, July 24, 2010
  • 13. Current Issues with JRuby on App Engine • Several seconds to “spin-up” a new JRuby instance • Some gems may need their extensions ported to Java • Not officially supported , but you have all that you need + 13 Saturday, July 24, 2010
  • 14. Install it Now sudo gem install google-appengine Everything you need installs as gems 14 Saturday, July 24, 2010
  • 15. App Engine Gems • Development Gems – appengine-sdk – appengine-tools . . . dev_appserver.rb & appcfg.rb • Runtime Gems – appengine-rack . . . . jruby-jars & jruby-rack – appengine-apis • Related Gems – dm-appengine – rails_appengine – rails_dm_datastore – rails_tiny_ds 15 Saturday, July 24, 2010
  • 16. App Engine JRuby APIs • AppEngine::Users • AppEngine::Datastore • AppEngine::Memcache • AppEngine::Mail • AppEngine::URLFetch • AppEngine::Images • AppEngine::Logger • AppEngine::XMPP • AppEngine::Labs::TaskQueue • AppEngine::OAuth • AppEngine::Blobstore 16 Saturday, July 24, 2010
  • 17. Mirah Charles Nutter 17 Saturday, July 24, 2010
  • 18. Me • Charles Oliver Nutter • JRuby co-lead • Ex-Java EE developer • @headius • headius@headius.com • blog.headius.com Saturday, July 24, 2010
  • 19. My Day Job • JRuby and JRuby-related extensions • JVM-based utilities and libraries (for JRuby?) • Bytecode generation • Mobile and embedded interests • Narrow, “system”-level scope Saturday, July 24, 2010
  • 20. My Problem • I love Ruby • I write Java all day for JRuby • How can I write Ruby all day? Saturday, July 24, 2010
  • 21. What If This... public class Foo { private int a; public Foo(int a) { this.a = a; } public void show() { System.out.println(a); } } Saturday, July 24, 2010
  • 22. ...Could Be This class Foo def initialize(a) @a = a end def show puts @a end end Saturday, July 24, 2010
  • 23. Mirah class Foo def initialize(a:int) @a = a end def show puts @a end end Saturday, July 24, 2010
  • 24. Mirah • A nicer way to write Java • Ruby syntax with modifications • Feels like Ruby • Compiles to Java/JVM • No runtime library Saturday, July 24, 2010
  • 25. Features From Ruby • Optional arguments ✓ • Internal iteration ✓ • Closures ✓ • Literals ✓ • String interpolation ✓ • Mixins, “open” classes (soon) Saturday, July 24, 2010
  • 26. Ruby puts “Hello, world!” Saturday, July 24, 2010
  • 27. Mirah puts “Hello, world!” Saturday, July 24, 2010
  • 28. Ruby public static __file__(Lruby/__dash_e__;Lorg/jruby/runtime/ThreadContext;Lorg/jruby/ runtime/builtin/IRubyObject;[Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/ Block;)Lorg/jruby/runtime/builtin/IRubyObject; @Lorg/jruby/anno/JRubyMethod;(name="__file__", frame=true, required=0, optional=0, rest=-2) L0 LINENUMBER 1 L0 ALOAD 1 ICONST_0 INVOKESTATIC ruby/__dash_e__.setPosition (Lorg/jruby/runtime/ThreadContext;I)V ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite0 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 2 ALOAD 0 ALOAD 1 GETFIELD org/jruby/runtime/ThreadContext.runtime : Lorg/jruby/Ruby; INVOKEVIRTUAL ruby/__dash_e__.getString0 (Lorg/jruby/Ruby;)Lorg/jruby/RubyString; INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/ jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/ runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; ARETURN Saturday, July 24, 2010
  • 29. Mirah public static void main(java.lang.String[]); Code: 0: getstatic #12; //Field java/lang/System.out:Ljava/ io/PrintStream; 3: ldc #14; //String Hello, world! 5: invokevirtual #20; //Method java/io/ PrintStream.println:(Ljava/lang/String;)V 8: return Saturday, July 24, 2010
  • 30. Mirah // Generated from DashE public class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println("Hello, world!"); } } Saturday, July 24, 2010
  • 31. Ruby def fib(a) if a < 2 a else fib(a - 1) + fib(a - 2) end end Saturday, July 24, 2010
  • 32. Mirah def fib(a:int) if a < 2 a else fib(a - 1) + fib(a - 2) end end Saturday, July 24, 2010
  • 33. Ruby public static method__0$RUBY$fib(Lruby/__dash_e__;Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;Lorg/jruby/runtime/Block;)Lorg/jruby/runtime/builtin/IRubyObject; @Lorg/jruby/anno/JRubyMethod;(name="fib", frame=true, required=1, optional=0, rest=-1) ALOAD 3 ASTORE 9 L0 LINENUMBER 1 L0 ALOAD 1 ICONST_0 INVOKESTATIC ruby/__dash_e__.setPosition (Lorg/jruby/runtime/ThreadContext;I)V ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite0 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 9 LDC 2 INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;J)Lorg/jruby/runtime/builtin/IRubyObject; INVOKEINTERFACE org/jruby/runtime/builtin/IRubyObject.isTrue ()Z IFEQ L1 ALOAD 9 GOTO L2 L1 FRAME FULL [ruby/__dash_e__ org/jruby/runtime/ThreadContext org/jruby/runtime/builtin/IRubyObject org/jruby/runtime/builtin/IRubyObject org/jruby/runtime/Block T T T T org/jruby/runtime/builtin/IRubyObject] [] ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite1 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite2 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 2 ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite3 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 9 LDC 1 INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;J)Lorg/jruby/runtime/builtin/IRubyObject; INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite4 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 2 ALOAD 0 INVOKEVIRTUAL ruby/__dash_e__.getCallSite5 ()Lorg/jruby/runtime/CallSite; ALOAD 1 ALOAD 2 ALOAD 9 LDC 2 INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;J)Lorg/jruby/runtime/builtin/IRubyObject; INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; INVOKEVIRTUAL org/jruby/runtime/CallSite.call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/ IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; L2 FRAME SAME1 org/jruby/runtime/builtin/IRubyObject ARETURN Saturday, July 24, 2010
  • 34. Mirah public static int fib(int); Code: 0: iload_0 1: iconst_2 2: if_icmplt 9 5: iconst_0 6: goto 10 9: iconst_1 10: ifeq 17 13: iload_0 14: goto 30 17: iload_0 18: iconst_1 19: isub 20: invokestatic #10; //Method fib:(I)I 23: iload_0 24: iconst_2 25: isub 26: invokestatic #10; //Method fib:(I)I 29: iadd 30: ireturn Saturday, July 24, 2010
  • 35. Mirah // Generated from DashE public class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { } public static int fib(int a) { return (a < 2) ? (a) : ((DashE.fib((a - 1)) + DashE.fib((a - 2)))); } } Saturday, July 24, 2010
  • 36. Ruby def foo(a = 1, b = 2) puts a + b end Saturday, July 24, 2010
  • 37. Mirah def foo(a:int = 1, b:int = 2) puts a + b end Saturday, July 24, 2010
  • 38. Mirah public static java.io.PrintStream foo(int a, int b) { java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println((a + b)); return temp$1; } public static java.io.PrintStream foo() { return foo(1); } public static java.io.PrintStream foo(int a) { return foo(a, 2); } Saturday, July 24, 2010
  • 39. Ruby a = [5,4,3,2,1] a.each do |x| puts x end Saturday, July 24, 2010
  • 40. Mirah a = [5,4,3,2,1] a.each do |x| puts x end Saturday, July 24, 2010
  • 41. Mirah // Generated from DashE public class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { java.util.List a = java.util.Collections.unmodifiableList( java.util.Arrays.asList(1, 2, 3, 4, 5)); java.util.Iterator __xform_tmp_1 = a.iterator(); label1: while (__xform_tmp_1.hasNext()) { java.lang.Object x = __xform_tmp_1.next(); label2: { java.io.PrintStream temp$3 = java.lang.System.out; temp$3.println(x); } } } } Saturday, July 24, 2010
  • 42. Ruby t = Thread.new do puts “in thread” end Saturday, July 24, 2010
  • 43. Mirah t = Thread.new do puts “in thread” end Saturday, July 24, 2010
  • 44. // Generated from DashE Mirah public class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { DashE.__xform_tmp_1 $binding = new DashE.__xform_tmp_1(); $binding.x = "in thread"; java.lang.Thread t = new java.lang.Thread(new DashE.__xform_tmp_2($binding)); } public static class __xform_tmp_1 extends java.lang.Object { java.lang.String x; } public static class __xform_tmp_2 extends java.lang.Object implements java.lang.Runnable { private DashE.__xform_tmp_1 binding; public __xform_tmp_2(DashE.__xform_tmp_1 binding) { this.binding = binding; } public void run() { DashE.__xform_tmp_1 $binding = this.binding; java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println($binding.x); } } } Saturday, July 24, 2010
  • 45. // Generated from DashE Mirah public class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { DashE.__xform_tmp_1 $binding = new DashE.__xform_tmp_1(); $binding.x = "in thread"; java.lang.Thread t = new java.lang.Thread(new DashE.__xform_tmp_2($binding)); } public static class __xform_tmp_1 extends java.lang.Object { java.lang.String x; } public static class __xform_tmp_2 extends java.lang.Object implements java.lang.Runnable { private DashE.__xform_tmp_1 binding; public __xform_tmp_2(DashE.__xform_tmp_1 binding) { this.binding = binding; } public void run() { DashE.__xform_tmp_1 $binding = this.binding; java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println($binding.x); } } } Saturday, July 24, 2010
  • 46. // Generated from DashE Mirah public class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { DashE.__xform_tmp_1 $binding = new DashE.__xform_tmp_1(); $binding.x = "in thread"; java.lang.Thread t = new java.lang.Thread(new DashE.__xform_tmp_2($binding)); } public static class __xform_tmp_1 extends java.lang.Object { java.lang.String x; } public static class __xform_tmp_2 extends java.lang.Object implements java.lang.Runnable { private DashE.__xform_tmp_1 binding; public __xform_tmp_2(DashE.__xform_tmp_1 binding) { this.binding = binding; } public void run() { DashE.__xform_tmp_1 $binding = this.binding; java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println($binding.x); } } } Saturday, July 24, 2010
  • 47. It’s Not Ruby • Using Java’s libraries and type system • No “eval” • No runtime-mutable classes • Ruby libraries will not work Saturday, July 24, 2010
  • 48. But It Feels Like Ruby! • Clean, lightweight syntax • Iteration, closures • Far less “ceremony” than Java • Performance equivalent to Java Saturday, July 24, 2010
  • 49. mirah.org Saturday, July 24, 2010
  • 50. Rails & Mirah Demos John Woodell 50 Saturday, July 24, 2010
  • 51. Saturday, July 24, 2010
  • 52. Saturday, July 24, 2010
  • 53. Benefits of Mirah on App Engine • New instances always spin-up in about a second • Dubious framework uses familiar Rails conventions • Code in Java or Ruby when Mirah lacks features you require • The generated Java source can be inspected at any time 53 Saturday, July 24, 2010
  • 54. Mirah apps should look familiar to Rubyists Saturday, July 24, 2010
  • 55. Mirah apps can use ERb templates Saturday, July 24, 2010
  • 56. The generated Java source can be inspected Saturday, July 24, 2010
  • 57. The ERb is transformed into method calls Saturday, July 24, 2010
  • 58. Your model definition is very concise Saturday, July 24, 2010
  • 59. Code is generated based on properties you define Saturday, July 24, 2010
  • 60. All the basic methods you need are generated Saturday, July 24, 2010
  • 61. Resources • Blog – http://jruby-appengine.blogspot.com • Code Site – http://code.google.com/p/appengine-jruby • Examples Apps – http://rails-primer.appspot.com – http://dubious-demo.appspot.com • Mirah Projects – http://github.com/headius/mirah – http://github.com/mirah/dubious 61 Saturday, July 24, 2010
  • 62. Saturday, July 24, 2010

×