• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Merb Day Keynote
 

Merb Day Keynote

on

  • 4,398 views

 

Statistics

Views

Total Views
4,398
Views on SlideShare
4,060
Embed Views
338

Actions

Likes
3
Downloads
33
Comments
0

8 Embeds 338

http://merbist.com 301
http://www.merboverheard.com 15
http://merboverheard.com 11
http://static.slideshare.net 6
http://www.hanrss.com 2
applewebdata://E3194B7C-D4E2-48D9-B912-B77781163DAC 1
http://www.linkedin.com 1
https://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Merb Day Keynote Merb Day Keynote Presentation Transcript

    • Merb 2.0 The long march into the future
    • Core Merb Principles
    • In Depth
    • Performance
    • Requests Per Second
    • Thin Mongrel
    • run proc do |env| [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end
    • class QuickApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end end run QuickApp.new
    • class QuickApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end end run QuickApp.new
    • Thin Mongrel
    • match(quot;/routerquot;).defer_to do |req, res| [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Helloquot; ] end
    • Thin Mongrel
    • class MyApp < Application def string quot;Stringquot; end end
    • class MyApp < Application def string quot;Stringquot; end end
    • Thin Mongrel
    • class MyApp < Application def index render end def string quot;Stringquot; end end
    • class MyApp < Application def index render end def string quot;Stringquot; end end
    • Close to the metal as possible
    • Close to the metal as you want
    • Performance Testing
    • KCacheGrind
    • use Merb::Rack::Profile
    • profile/url/callgrind.out.time
    • 5% or greater
    • 10% or greater
    • 10% or greater Merb::RenderMixin::_get_layout 10.05 %
    • Mini-demo
    • Concurrency
    • 20 16 12 8 4 0 1 2 4 8 16 32 Ideal concurrency curve
    • 1 request in 16ms (16ms/req)
    • 2 requests in 16ms (8ms/req)
    • 4 requests in 16ms (4ms/req)
    • 8 requests in 16ms (2ms/req)
    • 16 requests in 16ms (1ms/req)
    • 32 requests in 16ms (2req/ms)
    • 20 16 12 8 4 0 1 2 4 8 16 32 Ideal concurrency curve
    • Chart 10 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 Merb MRI concurrency curve
    • Chart 12 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 Merb JRuby (Mongrel) concurrency curve
    • Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Merb Glassfish concurrency curve
    • Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal
    • Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal
    • Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal (but it works)
    • Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal (but it works)
    • Threadsafety
    • Merb::Config[:use_mutex]
    • class User cattr_accessor :current end class Foo < Merb::Controller before do User.current = session.user end end
    • class User cattr_accessor :current end class Foo < FAIL Merb::Controller before do User.current = session.user end end
    • Shared state hurts puppies
    • Solutions
    • Thread-local
    • class User def self.current=(user) Thread.current[:user] = user end def self.current Thread.current[:user] end end class Foo < Merb::Controller before do User.current = session.user end end
    • Using a Hash across threads
    • Hash {:x => 5}
    • Hash {:x => 5} Thread 1 Thread 2
    • Hash {:x => 5} Thread 1 Thread 2
    • Hash {:x => 5} Thread 1 Thread 2 Read x
    • Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1”
    • Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x
    • Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x?
    • Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? no? return nil x=1
    • Mutex
    • Hash {:x => 5}
    • Hash {:x => 5} Thread 1 Thread 2
    • Hash {:x => 5} Thread 1 Thread 2 Read x is there an x? yes? return 5
    • Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? yes? return 5 x=1
    • Hash {:x => 5}
    • Hash {:x => 5} Thread 1 Thread 2
    • Hash {:x => 5} Thread 1 Thread 2 Write x=”1” clear x x=1
    • Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? yes? return 1 x=1
    • Mutexes make non-atomic operations atomic
    • Modularity
    • merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
    • merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
    • merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
    • merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency dependency quot;merb-slicesquot;, merb_gems_version 1 .1.4 quot;merb-auth-corequot;, merb_gems_version dependency uby quot;merb-auth-morequot;, merb_gems_version dependency dependency J R quot;merb-auth-slice-passwordquot;, merb_gems_version quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
    • merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency quot;merb-slicesquot;, merb_gems_version dependency quot;merb-auth-corequot;, merb_gems_version dependency quot;merb-auth-morequot;, merb_gems_version dependency quot;merb-auth-slice-passwordquot;, merb_gems_version dependency quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
    • merb_gems_version = quot;1.0.4quot; dm_gems_version = quot;0.9.7quot; dependency quot;merb-action-argsquot;, merb_gems_version dependency quot;merb-assetsquot;, merb_gems_version dependency quot;merb-cachequot;, merb_gems_version dependency quot;merb-helpersquot;, merb_gems_version dependency quot;merb-mailerquot;, merb_gems_version dependency .5+ quot;merb-slicesquot;, merb_gems_version dependency 1 .1 quot;merb-auth-corequot;, merb_gems_version dependency dependency by quot;merb-auth-morequot;, merb_gems_version Ru quot;merb-auth-slice-passwordquot;, merb_gems_version dependency J quot;merb-param-protectionquot;, merb_gems_version dependency quot;merb-exceptionsquot;, merb_gems_version dependency quot;dm-corequot;, dm_gems_version dependency quot;dm-aggregatesquot;, dm_gems_version dependency quot;dm-migrationsquot;, dm_gems_version dependency quot;dm-timestampsquot;, dm_gems_version dependency quot;dm-typesquot;, dm_gems_version dependency quot;dm-validationsquot;, dm_gems_version
    • @overridable
    • # This is a stub method so plugins can # implement param filtering if they want. # # ==== Parameters # params<Hash{Symbol => String}>:: # A list of params # # ==== Returns # Hash{Symbol => String}:: # A new list of params, filtered as desired # # :api: plugin # @overridable def self._filter_params(params) params end
    • class Articles < Application params_accessible :article => [:title, :body] end
    • class Articles < Application params_accessible :article => [:title, :body] end
    • class Articles < Application def self._filter_params(params) # deep_clone ret = Marshal.load(Marshal.dump(params)) ret[:post].reject! do |k,v| !k.in?(:title, :body) end end end
    • class Articles < Application def self._filter_params(params) # deep_clone ret = Marshal.load(Marshal.dump(params)) ret[:post].reject! do |k,v| !k.in?(:title, :body) end end end
    • # :api: public # @overridable def _template_location(ctx, type, ctrlr) _conditionally_append_extension( ctrlr ? quot;#{ctrlr}/#{ctx}quot; : quot;#{ctx}quot;, type) end
    • class Articles < Application def self._template_location( ctx, type, ctrlr) quot;#{ctrlr}.#{ctx}.#{type}quot; end end
    • class Articles < Application def self._template_location( ctx, type, ctrlr) quot;#{ctrlr}.#{ctx}.#{type}quot; end end
    • class Articles < Application def self._template_location( t” ay ctx, type, ctrlr) l ou r= “ ro lle nt quot;#{ctrlr}.#{ctx}.#{type}quot; co end end
    • class Articles < Application self.template_roots = [ [ Merb.root / quot;appquot; / quot;viewsquot;, :_template_location ], [ Merb.root / quot;my_viewsquot;, :_my_template_location ] ] end
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • >> MerbAuthSlicePassword::Sessions.template_roots #=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/ viewsquot;, :_template_location], [quot;/Library/Ruby/Gems/1.8/gems/ merb-auth-slice-password-1.0.4/app/ viewsquot;, :_slice_template_location], [quot;/Users/wycats/Code/wycats/ test/awesome/slices/merb-auth-slice-password/app/ viewsquot;, :_slice_template_location]]
    • def _slice_template_location(ctx, type, ctrlr) if ctrlr && ctrlr.include?('/') # skip first segment if given (which is the module name) segments = ctrlr.split('/') quot;#{segments[1,segments.length-1].join('/')}/#{ctx}.#{type}quot; else # default template location logic _template_location(ctx, type, ctrlr) end end
    • Templates
    • def load_template_io(path) file = Dir[ quot;#{path}.{#{template_extensions.join(',')}}quot; ].first File.open(file, quot;rquot;) if file end
    • def load_template_io(path) templates = { Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; / quot;index.html.erbquot; => quot;Hello worldquot;, Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; / quot;two.html.erbquot; => quot;Twoquot; } if templates[path + quot;.erbquot;] VirtualFile.new(templates[path + quot;.erbquot;], path + quot;.erbquot;) else file = Dir[ quot;#{path}.{#{template_extensions.join(',')}}quot; ].first File.open(file, quot;rquot;) if file end end
    • Merb::Router.prepare {default_routes} class TemplateIo < Merb::Controller def index render end def two render end end
    • Quick demo
    • Good Ruby citizen
    • Rubygems
    • Rubygems :(
    • Rubygems -- but getting :)
    • Working with community == helping the community
    • Rack
    • Rack middleware
    • Where is this going?
    • Apps as a first-class concept
    • module MyApp class TemplateIo < Application def index render end def two render end end end
    • module MyApp class TemplateIo < Application def index render end def two render end end end
    • module MyApp class TemplateIo < Application def index render MyApp::Application end def two render end end end
    • module MyApp extend Merb::App mount ::Blog, :at => quot;/blogquot; Config[:framework] = flat end
    • Blog::Config[:log_delimiter] = quot;BLOG: quot;
    • Admin Application/Framework
    • CMS Application
    • DB Admin Application
    • Slices on Steroids
    • Resources as a first-class concept
    • module MyApp class Resource < Merb::Resource def list(klass) klass.all end def get(klass, ids) klass.get(ids) end def authorized?(namespace, *args) user == quot;wycatsquot; end def user request.session.user end end end
    • Why?
    • DRYing up common idioms
    • Increasing flexibility (where needed)
    • Core principle: Simple cases can’t get harder
    • Further improve merb server
    • Short term
    • Long term
    • Dynamic worker pools
    • Remove need for nginx
    • Self-managing cluster
    • Additional modules
    • i18n
    • l10n
    • Feed syndication
    • Flat pages
    • More powerful router
    • Router directly to a view
    • even better resource()
    • Framework for OSS Apps
    • Authentication
    • User Management
    • Authorization
    • Note: Communication primitives
    • Tailored stacks
    • Designers
    • Web shops