Your SlideShare is downloading. ×
0
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 fr...
class QuickApp
  def call(env)
    [
      200,
      {quot;Content-Typequot; => quot;text/htmlquot;},
      quot;Hello fr...
Thin   Mongrel
match(quot;/routerquot;).defer_to do |req, res|
  [
    200,
    {quot;Content-Typequot; => quot;text/htmlquot;},
    quot...
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 concurr...
Chart 12
15.00


11.25


 7.50


 3.75


   0
        1      2      4      8    16     32




        Merb JRuby (Mongrel)...
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2    4    8      16   32   64   128   256




                Me...
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                    ...
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                    ...
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                    ...
Chart 13
15.00


11.25


 7.50


 3.75


   0
        1   2   4   8      16   32   64   128   256




                    ...
Threadsafety
Merb::Config[:use_mutex]
class User
  cattr_accessor :current
end

class Foo < Merb::Controller
  before do
    User.current = session.user
  end
e...
class User
  cattr_accessor :current
end

class Foo <  FAIL
            Merb::Controller
  before do
    User.current = se...
Shared state hurts puppies
Solutions
Thread-local
class User
  def self.current=(user)
    Thread.current[:user] = user
  end

  def self.current
    Thread.current[:user]
...
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”
                             clea...
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write x=”1”
                             ...
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write 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”
                             ...
Hash {:x => 5}
Hash {:x => 5}

Thread 1                    Thread 2
Hash {:x => 5}

Thread 1                    Thread 2

                       Write x=”1”
                             clea...
Hash {:x => 5}

  Thread 1                    Thread 2

   Read x                Write 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_gem...
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gem...
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gem...
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gem...
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gem...
merb_gems_version = quot;1.0.4quot;
dm_gems_version   = quot;0.9.7quot;

dependency   quot;merb-action-argsquot;, merb_gem...
@overridable
# This is a stub method so plugins can
# implement param filtering if they want.
#
# ==== Parameters
# params<Hash{Symbol ...
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(...
class Articles < Application
  def self._filter_params(params)
    # deep_clone
    ret =
      Marshal.load(Marshal.dump(...
# :api: public
# @overridable
def _template_location(ctx, type, ctrlr)
  _conditionally_append_extension(
    ctrlr ?
    ...
class Articles < Application
  def self._template_location(
    ctx, type, ctrlr)

    quot;#{ctrlr}.#{ctx}.#{type}quot;
 ...
class Articles < Application
  def self._template_location(
    ctx, type, ctrlr)

    quot;#{ctrlr}.#{ctx}.#{type}quot;
 ...
class Articles < Application
  def self._template_location(
                       t”
                   ay
    ctx, type,...
class Articles < Application
  self.template_roots = [
    [
       Merb.root / quot;appquot; / quot;viewsquot;,
       :_...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
>> MerbAuthSlicePassword::Sessions.template_roots
#=> [[quot;/Users/wycats/Code/wycats/test/awesome/app/
viewsquot;, :_tem...
def _slice_template_location(ctx, type, ctrlr)
  if ctrlr && ctrlr.include?('/')
    # skip first segment if given (which ...
Templates
def load_template_io(path)
  file = Dir[
    quot;#{path}.{#{template_extensions.join(',')}}quot;
  ].first
  File.open(fi...
def load_template_io(path)
  templates = {
    Merb.root / quot;appquot; / quot;viewsquot; / quot;template_ioquot; /
     ...
Merb::Router.prepare {default_routes}

class TemplateIo < Merb::Controller
  def index
    render
  end

  def two
    ren...
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
e...
module MyApp
  class TemplateIo < Application
    def index
      render
    end

    def two
      render
    end
  end
e...
module MyApp
  class TemplateIo < Application
    def index
      render        MyApp::Application
    end

    def two
  ...
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)
      ...
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
Merb Day Keynote
Upcoming SlideShare
Loading in...5
×

Merb Day Keynote

5,001

Published on

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,001
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
34
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Merb Day Keynote"

  1. 1. Merb 2.0 The long march into the future
  2. 2. Core Merb Principles
  3. 3. In Depth
  4. 4. Performance
  5. 5. Requests Per Second
  6. 6. Thin Mongrel
  7. 7. run proc do |env| [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end
  8. 8. class QuickApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end end run QuickApp.new
  9. 9. class QuickApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Hello from rackquot; ] end end run QuickApp.new
  10. 10. Thin Mongrel
  11. 11. match(quot;/routerquot;).defer_to do |req, res| [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Helloquot; ] end
  12. 12. Thin Mongrel
  13. 13. class MyApp < Application def string quot;Stringquot; end end
  14. 14. class MyApp < Application def string quot;Stringquot; end end
  15. 15. Thin Mongrel
  16. 16. class MyApp < Application def index render end def string quot;Stringquot; end end
  17. 17. class MyApp < Application def index render end def string quot;Stringquot; end end
  18. 18. Close to the metal as possible
  19. 19. Close to the metal as you want
  20. 20. Performance Testing
  21. 21. KCacheGrind
  22. 22. use Merb::Rack::Profile
  23. 23. profile/url/callgrind.out.time
  24. 24. 5% or greater
  25. 25. 10% or greater
  26. 26. 10% or greater Merb::RenderMixin::_get_layout 10.05 %
  27. 27. Mini-demo
  28. 28. Concurrency
  29. 29. 20 16 12 8 4 0 1 2 4 8 16 32 Ideal concurrency curve
  30. 30. 1 request in 16ms (16ms/req)
  31. 31. 2 requests in 16ms (8ms/req)
  32. 32. 4 requests in 16ms (4ms/req)
  33. 33. 8 requests in 16ms (2ms/req)
  34. 34. 16 requests in 16ms (1ms/req)
  35. 35. 32 requests in 16ms (2req/ms)
  36. 36. 20 16 12 8 4 0 1 2 4 8 16 32 Ideal concurrency curve
  37. 37. Chart 10 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 Merb MRI concurrency curve
  38. 38. Chart 12 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 Merb JRuby (Mongrel) concurrency curve
  39. 39. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Merb Glassfish concurrency curve
  40. 40. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal
  41. 41. Chart 13 15.00 11.25 7.50 3.75 0 1 2 4 8 16 32 64 128 256 Not ideal
  42. 42. 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)
  43. 43. 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)
  44. 44. Threadsafety
  45. 45. Merb::Config[:use_mutex]
  46. 46. class User cattr_accessor :current end class Foo < Merb::Controller before do User.current = session.user end end
  47. 47. class User cattr_accessor :current end class Foo < FAIL Merb::Controller before do User.current = session.user end end
  48. 48. Shared state hurts puppies
  49. 49. Solutions
  50. 50. Thread-local
  51. 51. 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
  52. 52. Using a Hash across threads
  53. 53. Hash {:x => 5}
  54. 54. Hash {:x => 5} Thread 1 Thread 2
  55. 55. Hash {:x => 5} Thread 1 Thread 2
  56. 56. Hash {:x => 5} Thread 1 Thread 2 Read x
  57. 57. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1”
  58. 58. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x
  59. 59. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x?
  60. 60. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? no? return nil x=1
  61. 61. Mutex
  62. 62. Hash {:x => 5}
  63. 63. Hash {:x => 5} Thread 1 Thread 2
  64. 64. Hash {:x => 5} Thread 1 Thread 2 Read x is there an x? yes? return 5
  65. 65. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? yes? return 5 x=1
  66. 66. Hash {:x => 5}
  67. 67. Hash {:x => 5} Thread 1 Thread 2
  68. 68. Hash {:x => 5} Thread 1 Thread 2 Write x=”1” clear x x=1
  69. 69. Hash {:x => 5} Thread 1 Thread 2 Read x Write x=”1” clear x is there an x? yes? return 1 x=1
  70. 70. Mutexes make non-atomic operations atomic
  71. 71. Modularity
  72. 72. 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
  73. 73. 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
  74. 74. 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
  75. 75. 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
  76. 76. 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
  77. 77. 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
  78. 78. @overridable
  79. 79. # 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
  80. 80. class Articles < Application params_accessible :article => [:title, :body] end
  81. 81. class Articles < Application params_accessible :article => [:title, :body] end
  82. 82. 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
  83. 83. 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
  84. 84. # :api: public # @overridable def _template_location(ctx, type, ctrlr) _conditionally_append_extension( ctrlr ? quot;#{ctrlr}/#{ctx}quot; : quot;#{ctx}quot;, type) end
  85. 85. class Articles < Application def self._template_location( ctx, type, ctrlr) quot;#{ctrlr}.#{ctx}.#{type}quot; end end
  86. 86. class Articles < Application def self._template_location( ctx, type, ctrlr) quot;#{ctrlr}.#{ctx}.#{type}quot; end end
  87. 87. 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
  88. 88. class Articles < Application self.template_roots = [ [ Merb.root / quot;appquot; / quot;viewsquot;, :_template_location ], [ Merb.root / quot;my_viewsquot;, :_my_template_location ] ] end
  89. 89. >> 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]]
  90. 90. >> 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]]
  91. 91. >> 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]]
  92. 92. >> 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]]
  93. 93. >> 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]]
  94. 94. >> 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]]
  95. 95. >> 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]]
  96. 96. 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
  97. 97. Templates
  98. 98. def load_template_io(path) file = Dir[ quot;#{path}.{#{template_extensions.join(',')}}quot; ].first File.open(file, quot;rquot;) if file end
  99. 99. 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
  100. 100. Merb::Router.prepare {default_routes} class TemplateIo < Merb::Controller def index render end def two render end end
  101. 101. Quick demo
  102. 102. Good Ruby citizen
  103. 103. Rubygems
  104. 104. Rubygems :(
  105. 105. Rubygems -- but getting :)
  106. 106. Working with community == helping the community
  107. 107. Rack
  108. 108. Rack middleware
  109. 109. Where is this going?
  110. 110. Apps as a first-class concept
  111. 111. module MyApp class TemplateIo < Application def index render end def two render end end end
  112. 112. module MyApp class TemplateIo < Application def index render end def two render end end end
  113. 113. module MyApp class TemplateIo < Application def index render MyApp::Application end def two render end end end
  114. 114. module MyApp extend Merb::App mount ::Blog, :at => quot;/blogquot; Config[:framework] = flat end
  115. 115. Blog::Config[:log_delimiter] = quot;BLOG: quot;
  116. 116. Admin Application/Framework
  117. 117. CMS Application
  118. 118. DB Admin Application
  119. 119. Slices on Steroids
  120. 120. Resources as a first-class concept
  121. 121. 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
  122. 122. Why?
  123. 123. DRYing up common idioms
  124. 124. Increasing flexibility (where needed)
  125. 125. Core principle: Simple cases can’t get harder
  126. 126. Further improve merb server
  127. 127. Short term
  128. 128. Long term
  129. 129. Dynamic worker pools
  130. 130. Remove need for nginx
  131. 131. Self-managing cluster
  132. 132. Additional modules
  133. 133. i18n
  134. 134. l10n
  135. 135. Feed syndication
  136. 136. Flat pages
  137. 137. More powerful router
  138. 138. Router directly to a view
  139. 139. even better resource()
  140. 140. Framework for OSS Apps
  141. 141. Authentication
  142. 142. User Management
  143. 143. Authorization
  144. 144. Note: Communication primitives
  145. 145. Tailored stacks
  146. 146. Designers
  147. 147. Web shops
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×