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

Published on

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

No Downloads
Views
Total Views
3,030
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
29
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

×