Merb Day Keynote

  • 4,883 views
Uploaded on

 

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
4,883
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
33
Comments
0
Likes
3

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