SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
Saturday, July 24, 2010
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
Google App Engine
               3



Saturday, July 24, 2010
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
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
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
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
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
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
JRuby on App Engine
              10



Saturday, July 24, 2010
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
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
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
Install it Now

                     sudo gem install google-appengine



                          Everything you need installs as gems


              14



Saturday, July 24, 2010
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
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
Mirah
                          Charles Nutter




              17



Saturday, July 24, 2010
Me
                     • Charles Oliver Nutter
                     • JRuby co-lead
                     • Ex-Java EE developer
                     • @headius
                     • headius@headius.com
                     • blog.headius.com
Saturday, July 24, 2010
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
My Problem

                     • I love Ruby
                     • I write Java all day for JRuby
                     • How can I write Ruby all day?


Saturday, July 24, 2010
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
...Could Be This
                          class Foo
                            def initialize(a)
                              @a = a
                            end

                            def show
                              puts @a
                            end
                          end

Saturday, July 24, 2010
Mirah
                          class Foo
                            def initialize(a:int)
                              @a = a
                            end

                            def show
                              puts @a
                            end
                          end

Saturday, July 24, 2010
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
Features From Ruby
                     • Optional arguments ✓
                     • Internal iteration ✓
                     • Closures ✓
                     • Literals ✓
                     • String interpolation ✓
                     • Mixins, “open” classes (soon)
Saturday, July 24, 2010
Ruby


                          puts “Hello, world!”




Saturday, July 24, 2010
Mirah


                          puts “Hello, world!”




Saturday, July 24, 2010
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
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
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
Ruby
                          def fib(a)
                            if a < 2
                              a
                            else
                              fib(a - 1) + fib(a - 2)
                            end
                          end



Saturday, July 24, 2010
Mirah
                          def fib(a:int)
                            if a < 2
                              a
                            else
                              fib(a - 1) + fib(a - 2)
                            end
                          end



Saturday, July 24, 2010
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
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
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
Ruby


                          def foo(a = 1, b = 2)
                            puts a + b
                          end




Saturday, July 24, 2010
Mirah


                          def foo(a:int = 1, b:int = 2)
                            puts a + b
                          end




Saturday, July 24, 2010
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
Ruby

                          a = [5,4,3,2,1]
                          a.each do |x|
                            puts x
                          end




Saturday, July 24, 2010
Mirah

                          a = [5,4,3,2,1]
                          a.each do |x|
                            puts x
                          end




Saturday, July 24, 2010
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
Ruby


                          t = Thread.new do
                            puts “in thread”
                          end




Saturday, July 24, 2010
Mirah


                          t = Thread.new do
                            puts “in thread”
                          end




Saturday, July 24, 2010
// 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
// 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
// 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
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
But It Feels Like Ruby!

                     • Clean, lightweight syntax
                     • Iteration, closures
                     • Far less “ceremony” than Java
                     • Performance equivalent to Java

Saturday, July 24, 2010
mirah.org



Saturday, July 24, 2010
Rails & Mirah Demos
                           John Woodell




              50



Saturday, July 24, 2010
Saturday, July 24, 2010
Saturday, July 24, 2010
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
Mirah apps should look familiar to Rubyists




Saturday, July 24, 2010
Mirah apps can use ERb templates




Saturday, July 24, 2010
The generated Java source can be inspected




Saturday, July 24, 2010
The ERb is transformed into method calls




Saturday, July 24, 2010
Your model definition is very concise




Saturday, July 24, 2010
Code is generated based on properties you define




Saturday, July 24, 2010
All the basic methods you need are generated




Saturday, July 24, 2010
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
Saturday, July 24, 2010

Weitere ähnliche Inhalte

Ähnlich wie Oscon 2010

Gaelyk - SpringOne2GX - 2010 - Guillaume Laforge
Gaelyk - SpringOne2GX - 2010 - Guillaume LaforgeGaelyk - SpringOne2GX - 2010 - Guillaume Laforge
Gaelyk - SpringOne2GX - 2010 - Guillaume LaforgeGuillaume Laforge
 
Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...
Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...
Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...Codecamp Romania
 
JavaScript Library Overview (Ajax Exp West 2007)
JavaScript Library Overview (Ajax Exp West 2007)JavaScript Library Overview (Ajax Exp West 2007)
JavaScript Library Overview (Ajax Exp West 2007)jeresig
 
Feature Bits at LSSC10
Feature  Bits at LSSC10Feature  Bits at LSSC10
Feature Bits at LSSC10Erik Sowa
 
01/2009 - Portral development with liferay
01/2009 - Portral development with liferay01/2009 - Portral development with liferay
01/2009 - Portral development with liferaydaveayan
 
JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)jeresig
 
Laug Mootools And Common Js
Laug   Mootools And Common JsLaug   Mootools And Common Js
Laug Mootools And Common JsSkills Matter
 
Best Practices in Widget Development - Examples and Counterexamples
Best Practices in Widget Development  - Examples and CounterexamplesBest Practices in Widget Development  - Examples and Counterexamples
Best Practices in Widget Development - Examples and CounterexamplesROLE Project
 
Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)
Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)
Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)Werner Keil
 
Google App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGoogle App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGuillaume Laforge
 

Ähnlich wie Oscon 2010 (20)

App Engine Meetup
App Engine MeetupApp Engine Meetup
App Engine Meetup
 
Gaelyk - SpringOne2GX - 2010 - Guillaume Laforge
Gaelyk - SpringOne2GX - 2010 - Guillaume LaforgeGaelyk - SpringOne2GX - 2010 - Guillaume Laforge
Gaelyk - SpringOne2GX - 2010 - Guillaume Laforge
 
WSGI, Django, Gunicorn
WSGI, Django, GunicornWSGI, Django, Gunicorn
WSGI, Django, Gunicorn
 
Slideshare presentation
Slideshare presentationSlideshare presentation
Slideshare presentation
 
Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...
Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...
Vlad Zelinschi - Embrace Native JavaScript (the anti-plugins talk) - Codecamp...
 
Paul Querna - libcloud
Paul Querna - libcloudPaul Querna - libcloud
Paul Querna - libcloud
 
JavaScript Library Overview (Ajax Exp West 2007)
JavaScript Library Overview (Ajax Exp West 2007)JavaScript Library Overview (Ajax Exp West 2007)
JavaScript Library Overview (Ajax Exp West 2007)
 
Feature Bits at LSSC10
Feature  Bits at LSSC10Feature  Bits at LSSC10
Feature Bits at LSSC10
 
01/2009 - Portral development with liferay
01/2009 - Portral development with liferay01/2009 - Portral development with liferay
01/2009 - Portral development with liferay
 
Stackato v2
Stackato v2Stackato v2
Stackato v2
 
JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)
 
Stackato v5
Stackato v5Stackato v5
Stackato v5
 
Node.js
Node.jsNode.js
Node.js
 
Stackato v4
Stackato v4Stackato v4
Stackato v4
 
Laug Mootools And Common Js
Laug   Mootools And Common JsLaug   Mootools And Common Js
Laug Mootools And Common Js
 
Best Practices in Widget Development - Examples and Counterexamples
Best Practices in Widget Development  - Examples and CounterexamplesBest Practices in Widget Development  - Examples and Counterexamples
Best Practices in Widget Development - Examples and Counterexamples
 
Stackato
StackatoStackato
Stackato
 
Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)
Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)
Enterprise 2.0 using Social Frameworks like Agorava (SMWHH 2014)
 
JRubyConf 2009
JRubyConf 2009JRubyConf 2009
JRubyConf 2009
 
Google App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGoogle App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and Gaelyk
 

Mehr von John Woodell

Deploying and Maintaining an Enterprise OpenLDAP Directory
Deploying and Maintaining an Enterprise OpenLDAP DirectoryDeploying and Maintaining an Enterprise OpenLDAP Directory
Deploying and Maintaining an Enterprise OpenLDAP DirectoryJohn Woodell
 
Enterprise Mail and Calendaring with Open Software
Enterprise Mail and Calendaring with Open SoftwareEnterprise Mail and Calendaring with Open Software
Enterprise Mail and Calendaring with Open SoftwareJohn Woodell
 
Appengine ja-night-10
Appengine ja-night-10Appengine ja-night-10
Appengine ja-night-10John Woodell
 

Mehr von John Woodell (6)

Deploying and Maintaining an Enterprise OpenLDAP Directory
Deploying and Maintaining an Enterprise OpenLDAP DirectoryDeploying and Maintaining an Enterprise OpenLDAP Directory
Deploying and Maintaining an Enterprise OpenLDAP Directory
 
Enterprise Mail and Calendaring with Open Software
Enterprise Mail and Calendaring with Open SoftwareEnterprise Mail and Calendaring with Open Software
Enterprise Mail and Calendaring with Open Software
 
Appengine ja-night-10
Appengine ja-night-10Appengine ja-night-10
Appengine ja-night-10
 
Rejectkaigi 2010
Rejectkaigi 2010Rejectkaigi 2010
Rejectkaigi 2010
 
Rubypalooza 2009
Rubypalooza 2009Rubypalooza 2009
Rubypalooza 2009
 
RubyConf 2009
RubyConf 2009RubyConf 2009
RubyConf 2009
 

Oscon 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
  • 50. Rails & Mirah Demos John Woodell 50 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