rails 2.1.2 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (221) hide show
  1. data/CHANGELOG +27 -3
  2. data/Rakefile +70 -10
  3. data/bin/about +0 -0
  4. data/bin/console +0 -0
  5. data/bin/destroy +0 -0
  6. data/bin/generate +0 -0
  7. data/bin/performance/benchmarker +0 -0
  8. data/bin/performance/profiler +0 -0
  9. data/bin/performance/request +0 -0
  10. data/bin/plugin +0 -0
  11. data/bin/process/inspector +0 -0
  12. data/bin/process/reaper +0 -0
  13. data/bin/process/spawner +0 -0
  14. data/bin/runner +0 -0
  15. data/bin/server +0 -0
  16. data/config.ru +17 -0
  17. data/configs/apache.conf +0 -0
  18. data/configs/databases/ibm_db.yml +62 -0
  19. data/configs/databases/mysql.yml +3 -0
  20. data/configs/databases/postgresql.yml +3 -0
  21. data/configs/databases/sqlite2.yml +3 -0
  22. data/configs/databases/sqlite3.yml +3 -0
  23. data/configs/locales/en.yml +5 -0
  24. data/dispatches/dispatch.fcgi +1 -1
  25. data/dispatches/dispatch.rb +2 -2
  26. data/dispatches/gateway.cgi +2 -2
  27. data/doc/README_FOR_APP +5 -2
  28. data/doc/guides/html/2_2_release_notes.html +1185 -0
  29. data/doc/guides/html/actioncontroller_basics.html +1270 -0
  30. data/doc/guides/html/activerecord_validations_callbacks.html +749 -0
  31. data/doc/guides/html/association_basics.html +2585 -0
  32. data/doc/guides/html/authors.html +240 -0
  33. data/doc/guides/html/benchmarking_and_profiling.html +1018 -0
  34. data/doc/guides/html/caching_with_rails.html +583 -0
  35. data/doc/guides/html/command_line.html +434 -0
  36. data/doc/guides/html/configuring.html +438 -0
  37. data/doc/guides/html/creating_plugins.html +1594 -0
  38. data/doc/guides/html/debugging_rails_applications.html +1175 -0
  39. data/doc/guides/html/finders.html +1090 -0
  40. data/doc/guides/html/form_helpers.html +638 -0
  41. data/doc/guides/html/getting_started_with_rails.html +2066 -0
  42. data/doc/guides/html/index.html +349 -0
  43. data/doc/guides/html/layouts_and_rendering.html +1406 -0
  44. data/doc/guides/html/migrations.html +921 -0
  45. data/doc/guides/html/routing_outside_in.html +2213 -0
  46. data/doc/guides/html/security.html +1346 -0
  47. data/doc/guides/html/testing_rails_applications.html +1859 -0
  48. data/doc/guides/source/2_2_release_notes.txt +435 -0
  49. data/doc/guides/source/actioncontroller_basics/changelog.txt +5 -0
  50. data/doc/guides/source/actioncontroller_basics/cookies.txt +34 -0
  51. data/doc/guides/source/actioncontroller_basics/csrf.txt +32 -0
  52. data/doc/guides/source/actioncontroller_basics/filters.txt +119 -0
  53. data/doc/guides/source/actioncontroller_basics/http_auth.txt +24 -0
  54. data/doc/guides/source/actioncontroller_basics/index.txt +40 -0
  55. data/doc/guides/source/actioncontroller_basics/introduction.txt +9 -0
  56. data/doc/guides/source/actioncontroller_basics/methods.txt +39 -0
  57. data/doc/guides/source/actioncontroller_basics/parameter_filtering.txt +14 -0
  58. data/doc/guides/source/actioncontroller_basics/params.txt +93 -0
  59. data/doc/guides/source/actioncontroller_basics/request_response_objects.txt +43 -0
  60. data/doc/guides/source/actioncontroller_basics/rescue.txt +67 -0
  61. data/doc/guides/source/actioncontroller_basics/session.txt +187 -0
  62. data/doc/guides/source/actioncontroller_basics/streaming.txt +91 -0
  63. data/doc/guides/source/actioncontroller_basics/verification.txt +40 -0
  64. data/doc/guides/source/active_record_basics.txt +181 -0
  65. data/doc/guides/source/activerecord_validations_callbacks.txt +404 -0
  66. data/doc/guides/source/association_basics.txt +1840 -0
  67. data/doc/guides/source/authors.txt +39 -0
  68. data/doc/guides/source/benchmarking_and_profiling/appendix.txt +95 -0
  69. data/doc/guides/source/benchmarking_and_profiling/digging_deeper.txt +105 -0
  70. data/doc/guides/source/benchmarking_and_profiling/edge_rails_features.txt +185 -0
  71. data/doc/guides/source/benchmarking_and_profiling/gameplan.txt +27 -0
  72. data/doc/guides/source/benchmarking_and_profiling/index.txt +242 -0
  73. data/doc/guides/source/benchmarking_and_profiling/rubyprof.txt +179 -0
  74. data/doc/guides/source/benchmarking_and_profiling/statistics.txt +57 -0
  75. data/doc/guides/source/caching_with_rails.txt +367 -0
  76. data/doc/guides/source/command_line.txt +147 -0
  77. data/doc/guides/source/configuring.txt +225 -0
  78. data/doc/guides/source/creating_plugins/acts_as_yaffle.txt +191 -0
  79. data/doc/guides/source/creating_plugins/appendix.txt +46 -0
  80. data/doc/guides/source/creating_plugins/controllers.txt +59 -0
  81. data/doc/guides/source/creating_plugins/core_ext.txt +123 -0
  82. data/doc/guides/source/creating_plugins/custom_route.txt +69 -0
  83. data/doc/guides/source/creating_plugins/gem.txt +1 -0
  84. data/doc/guides/source/creating_plugins/generator_method.txt +89 -0
  85. data/doc/guides/source/creating_plugins/helpers.txt +51 -0
  86. data/doc/guides/source/creating_plugins/index.txt +52 -0
  87. data/doc/guides/source/creating_plugins/migration_generator.txt +156 -0
  88. data/doc/guides/source/creating_plugins/models.txt +76 -0
  89. data/doc/guides/source/creating_plugins/odds_and_ends.txt +69 -0
  90. data/doc/guides/source/creating_plugins/test_setup.txt +230 -0
  91. data/doc/guides/source/debugging_rails_applications.txt +733 -0
  92. data/doc/guides/source/finders.txt +668 -0
  93. data/doc/guides/source/form_helpers.txt +345 -0
  94. data/doc/guides/source/getting_started_with_rails.txt +1256 -0
  95. data/doc/guides/source/images/belongs_to.png +0 -0
  96. data/doc/guides/source/images/bullet.gif +0 -0
  97. data/doc/guides/source/images/csrf.png +0 -0
  98. data/doc/guides/source/images/habtm.png +0 -0
  99. data/doc/guides/source/images/has_many.png +0 -0
  100. data/doc/guides/source/images/has_many_through.png +0 -0
  101. data/doc/guides/source/images/has_one.png +0 -0
  102. data/doc/guides/source/images/has_one_through.png +0 -0
  103. data/doc/guides/source/images/header_backdrop.png +0 -0
  104. data/doc/guides/source/images/icons/README +5 -0
  105. data/doc/guides/source/images/icons/callouts/1.png +0 -0
  106. data/doc/guides/source/images/icons/callouts/10.png +0 -0
  107. data/doc/guides/source/images/icons/callouts/11.png +0 -0
  108. data/doc/guides/source/images/icons/callouts/12.png +0 -0
  109. data/doc/guides/source/images/icons/callouts/13.png +0 -0
  110. data/doc/guides/source/images/icons/callouts/14.png +0 -0
  111. data/doc/guides/source/images/icons/callouts/15.png +0 -0
  112. data/doc/guides/source/images/icons/callouts/2.png +0 -0
  113. data/doc/guides/source/images/icons/callouts/3.png +0 -0
  114. data/doc/guides/source/images/icons/callouts/4.png +0 -0
  115. data/doc/guides/source/images/icons/callouts/5.png +0 -0
  116. data/doc/guides/source/images/icons/callouts/6.png +0 -0
  117. data/doc/guides/source/images/icons/callouts/7.png +0 -0
  118. data/doc/guides/source/images/icons/callouts/8.png +0 -0
  119. data/doc/guides/source/images/icons/callouts/9.png +0 -0
  120. data/doc/guides/source/images/icons/caution.png +0 -0
  121. data/doc/guides/source/images/icons/example.png +0 -0
  122. data/doc/guides/source/images/icons/home.png +0 -0
  123. data/doc/guides/source/images/icons/important.png +0 -0
  124. data/doc/guides/source/images/icons/next.png +0 -0
  125. data/doc/guides/source/images/icons/note.png +0 -0
  126. data/doc/guides/source/images/icons/prev.png +0 -0
  127. data/doc/guides/source/images/icons/tip.png +0 -0
  128. data/doc/guides/source/images/icons/up.png +0 -0
  129. data/doc/guides/source/images/icons/warning.png +0 -0
  130. data/doc/guides/source/images/polymorphic.png +0 -0
  131. data/doc/guides/source/images/rails_logo_remix.gif +0 -0
  132. data/doc/guides/source/images/ruby_on_rails_by_mike_rundle2.gif +0 -0
  133. data/doc/guides/source/images/session_fixation.png +0 -0
  134. data/doc/guides/source/index.txt +118 -0
  135. data/doc/guides/source/layouts_and_rendering.txt +982 -0
  136. data/doc/guides/source/migrations/anatomy_of_a_migration.txt +85 -0
  137. data/doc/guides/source/migrations/changelog.txt +5 -0
  138. data/doc/guides/source/migrations/creating_a_migration.txt +109 -0
  139. data/doc/guides/source/migrations/foreign_keys.txt +8 -0
  140. data/doc/guides/source/migrations/index.txt +22 -0
  141. data/doc/guides/source/migrations/rakeing_around.txt +111 -0
  142. data/doc/guides/source/migrations/scheming.txt +47 -0
  143. data/doc/guides/source/migrations/using_models_in_migrations.txt +46 -0
  144. data/doc/guides/source/migrations/writing_a_migration.txt +159 -0
  145. data/doc/guides/source/routing_outside_in.txt +986 -0
  146. data/doc/guides/source/security.txt +984 -0
  147. data/doc/guides/source/stylesheets/base.css +358 -0
  148. data/doc/guides/source/stylesheets/forms.css +35 -0
  149. data/doc/guides/source/stylesheets/more.css +82 -0
  150. data/doc/guides/source/templates/guides.html.erb +97 -0
  151. data/doc/guides/source/templates/inline.css +165 -0
  152. data/doc/guides/source/testing_rails_applications.txt +995 -0
  153. data/environments/boot.rb +2 -2
  154. data/environments/environment.rb +9 -1
  155. data/environments/production.rb +3 -1
  156. data/helpers/performance_test.rb +9 -0
  157. data/html/500.html +4 -1
  158. data/html/javascripts/controls.js +72 -72
  159. data/html/javascripts/dragdrop.js +165 -164
  160. data/html/javascripts/effects.js +173 -165
  161. data/html/javascripts/prototype.js +362 -267
  162. data/lib/commands/console.rb +13 -0
  163. data/lib/commands/dbconsole.rb +2 -2
  164. data/lib/commands/ncgi/listener +2 -2
  165. data/lib/commands/ncgi/tracker +2 -2
  166. data/lib/commands/plugin.rb +41 -24
  167. data/lib/commands/process/spawner.rb +4 -4
  168. data/lib/commands/runner.rb +1 -1
  169. data/lib/commands/server.rb +11 -1
  170. data/lib/commands/servers/thin.rb +25 -0
  171. data/lib/fcgi_handler.rb +1 -3
  172. data/lib/initializer.rb +162 -39
  173. data/lib/performance_test_help.rb +5 -0
  174. data/lib/rails/gem_builder.rb +3 -3
  175. data/lib/rails/gem_dependency.rb +155 -33
  176. data/lib/rails/mongrel_server/commands.rb +1 -1
  177. data/lib/rails/plugin.rb +10 -2
  178. data/lib/rails/rack.rb +6 -0
  179. data/lib/rails/rack/logger.rb +28 -0
  180. data/lib/rails/rack/static.rb +35 -0
  181. data/lib/rails/vendor_gem_source_index.rb +140 -0
  182. data/lib/rails/version.rb +1 -1
  183. data/lib/rails_generator/commands.rb +10 -16
  184. data/lib/rails_generator/generated_attribute.rb +4 -0
  185. data/lib/rails_generator/generators/applications/app/app_generator.rb +9 -3
  186. data/lib/rails_generator/generators/components/controller/controller_generator.rb +1 -1
  187. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -1
  188. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +1 -1
  189. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +2 -2
  190. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +1 -1
  191. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +2 -3
  192. data/lib/rails_generator/generators/components/model/model_generator.rb +1 -1
  193. data/lib/rails_generator/generators/components/model/templates/model.rb +3 -0
  194. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +1 -1
  195. data/lib/rails_generator/generators/components/observer/observer_generator.rb +1 -1
  196. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +1 -1
  197. data/lib/rails_generator/generators/components/performance_test/USAGE +8 -0
  198. data/lib/rails_generator/generators/components/performance_test/performance_test_generator.rb +16 -0
  199. data/lib/rails_generator/generators/components/performance_test/templates/performance_test.rb +9 -0
  200. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +11 -11
  201. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +1 -0
  202. data/lib/rails_generator/generators/components/plugin/templates/test_helper.rb +3 -0
  203. data/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +4 -4
  204. data/lib/rails_generator/generators/components/resource/resource_generator.rb +2 -2
  205. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +1 -1
  206. data/lib/rails_generator/generators/components/scaffold/USAGE +9 -5
  207. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +10 -3
  208. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +7 -7
  209. data/lib/rails_generator/scripts.rb +1 -1
  210. data/lib/rails_generator/scripts/destroy.rb +6 -7
  211. data/lib/rails_generator/secret_key_generator.rb +5 -147
  212. data/lib/tasks/annotations.rake +8 -11
  213. data/lib/tasks/databases.rake +42 -15
  214. data/lib/tasks/documentation.rake +15 -0
  215. data/lib/tasks/framework.rake +5 -1
  216. data/lib/tasks/gems.rake +24 -8
  217. data/lib/tasks/misc.rake +3 -4
  218. data/lib/tasks/testing.rake +25 -4
  219. data/lib/test_help.rb +1 -2
  220. data/lib/webrick_server.rb +2 -11
  221. metadata +165 -9
@@ -0,0 +1,39 @@
1
+ About the Authors
2
+ =================
3
+
4
+ .Frederick Cheung
5
+ [[fcheung]]
6
+ ***********************************************************
7
+ Frederick Cheung is Chief Wizard at Texperts where he has been using Rails since 2006.
8
+ He is based in Cambridge (UK) and when not consuming fine ales he blogs at http://www.spacevatican.org[spacevatican.org].
9
+ ***********************************************************
10
+
11
+ .Mike Gunderloy
12
+ [[mgunderloy]]
13
+ ***********************************************************
14
+ Mike Gunderloy is an independent consultant who brings 25 years of experience in a variety of languages to bear on his current
15
+ work with Rails. His near-daily links and other blogging can be found at http://afreshcup.com[A Fresh Cup].
16
+ ***********************************************************
17
+
18
+ .Emilio Tagua
19
+ [[miloops]]
20
+ ***********************************************************
21
+ Emilio Tagua -- a.k.a. miloops -- is an Argentinian entrepreneur, developer, open source contributor and Rails evangelist.
22
+ Cofounder of http://www.eventioz.com[Eventioz]. He has been using Rails since 2006 and contributing since early 2008.
23
+ Can be found at gmail, twitter, freenode, everywhere as miloops.
24
+ ***********************************************************
25
+
26
+ .Heiko Webers
27
+ [[hawe]]
28
+ ***********************************************************
29
+ Heiko Webers is the founder of http://www.bauland42.de[bauland42], a German web application security consulting and development
30
+ company focused on Ruby on Rails. He blogs at http://www.rorsecurity.info. After 10 years of desktop application development,
31
+ Heiko has rarely looked back.
32
+ ***********************************************************
33
+
34
+ .Tore Darell
35
+ [[toretore]]
36
+ ***********************************************************
37
+ Tore Darell is an independent developer based in Menton, France who specialises in cruft-free web applications using Ruby, Rails
38
+ and unobtrusive JavaScript. His home on the internet is his blog http://tore.darell.no/[Sneaky Abstractions].
39
+ ***********************************************************
@@ -0,0 +1,95 @@
1
+ == Other Profiling Tools ==
2
+
3
+ There are a lot of great profiling tools out there. Some free, some not so free. This is a sort list detailing some of them.
4
+
5
+ === httperf ===
6
+ http://www.hpl.hp.com/research/linux/httperf/[http://www.hpl.hp.com/research/linux/httperf/]
7
+
8
+ A necessary tool in your arsenal. Very useful for load testing your website.
9
+
10
+ #TODO write and link to a short article on how to use httperf. Anybody have a good tutorial availble.
11
+
12
+
13
+ === Rails Analyzer ===
14
+
15
+ The Rails Analyzer project contains a collection of tools for Rails. It's open source and pretty speedy. It's not being actively worked on but is still contains some very useful tools.
16
+
17
+ * The Production Log Analyzer examines Rails log files and gives back a report. It also includes action_grep which will give you all log results for a particular action.
18
+
19
+ * The Action Profiler similar to Ruby-Prof profiler.
20
+
21
+ * rails_stat which gives a live counter of requests per second of a running Rails app.
22
+
23
+ * The SQL Dependency Grapher allows you to visualize the frequency of table dependencies in a Rails application.
24
+
25
+ Their project homepage can be found at http://rails-analyzer.rubyforge.org/[http://rails-analyzer.rubyforge.org/]
26
+
27
+ The one major caveat is that it needs your log to be in a different format from how rails sets it up specifically SyslogLogger.
28
+
29
+
30
+ ==== SyslogLogger ====
31
+
32
+ SyslogLogger is a Logger work-alike that logs via syslog instead of to a file. You can add SyslogLogger to your Rails production environment to aggregate logs between multiple machines.
33
+
34
+ More information can be found out at http://rails-analyzer.rubyforge.org/hacks/classes/SyslogLogger.html[http://rails-analyzer.rubyforge.org/hacks/classes/SyslogLogger.html]
35
+
36
+ If you don't have access to your machines root system or just want something a bit easier to implement there is also a module developed by Geoffrey Grosenbach
37
+
38
+ ==== A Hodel 3000 Compliant Logger for the Rest of Us ====
39
+
40
+ Directions taken from
41
+ http://topfunky.net/svn/plugins/hodel_3000_compliant_logger/lib/hodel_3000_compliant_logger.rb[link to module file]
42
+
43
+ Just put the module in your lib directory and add this to your environment.rb in it's config portion.
44
+
45
+ ------------------------------------------------------------
46
+ require 'hodel_3000_compliant_logger'
47
+ config.logger = Hodel3000CompliantLogger.new(config.log_path)
48
+ -------------------------------------------------------------
49
+
50
+ It's that simple. Your log output on restart should look like this.
51
+
52
+ .Hodel 3000 Example
53
+ ----------------------------------------------------------------------------
54
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]:
55
+ Parameters: {"action"=>"shipping", "controller"=>"checkout"}
56
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]: 
57
+ [4;36;1mBook Columns (0.003155) SHOW FIELDS FROM `books`
58
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]: 
59
+ [4;35;1mBook Load (0.000881) SELECT * FROM `books` WHERE (`books`.`id` = 1 AND (`books`.`sold` = 1)) 
60
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]: 
61
+ [4;36;1mShippingAddress Columns (0.002683) SHOW FIELDS FROM `shipping_addresses`
62
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]: 
63
+ [4;35;1mBook Load (0.000362) SELECT ounces FROM `books` WHERE (`books`.`id` = 1) 
64
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]:
65
+ Rendering template within layouts/application
66
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]:
67
+ Rendering checkout/shipping
68
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]: 
69
+ [4;36;1mBook Load (0.000548) SELECT * FROM `books`
70
+ WHERE (sold = 0) LIMIT 3
71
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]: 
72
+ [4;35;1mAuthor Columns (0.002571) SHOW FIELDS FROM `authors`
73
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]:
74
+ Author Load (0.000811) SELECT * FROM `authors` WHERE (`authors`.`id` = 1) 
75
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]:
76
+ Rendered store/_new_books (0.01358)
77
+ Jul 15 11:45:43 matthew-bergmans-macbook-pro-15 rails[16207]:
78
+ Completed in 0.37297 (2 reqs/sec) | Rendering: 0.02971 (7%) | DB: 0.01697 (4%) | 200 OK [https://secure.jeffbooks/checkout/shipping]
79
+ ----------------------------------------------------------------------------
80
+
81
+ === Palmist ===
82
+ An open source mysql query analyzer. Full featured and easy to work with. Also requires Hodel 3000
83
+ http://www.flyingmachinestudios.com/projects/[http://www.flyingmachinestudios.com/projects/]
84
+
85
+ === New Relic ===
86
+ http://www.newrelic.com/[http://www.newrelic.com/]
87
+
88
+ Pretty nifty performance tools, pricey though. They do have a basic free
89
+ service both for when in development and when you put your application into production. Very simple installation and signup.
90
+
91
+ #TODO more in-depth without being like an advertisement.
92
+
93
+ ==== Manage ====
94
+
95
+ Like new relic a production monitoring tool.
@@ -0,0 +1,105 @@
1
+ == Real Life Example ==
2
+ === The setup ===
3
+
4
+ So I have been building this application for the last month and feel pretty good about the ruby code. I'm readying it for beta testers when I discover to my shock that with less then twenty people it starts to crash. It's a pretty simple Ecommerce site so I'm very confused by what I'm seeing. On running looking through my log files I find to my shock that the lowest time for a page run is running around 240 ms. My database finds aren't the problems so I'm lost as to what is happening to cause all this. Lets run a benchmark.
5
+
6
+
7
+ [source, ruby]
8
+ ----------------------------------------------------------------------------
9
+ class HomepageTest < ActionController::PerformanceTest
10
+ # Replace this with your real tests.
11
+ def test_homepage
12
+ get '/'
13
+ end
14
+ end
15
+ ----------------------------------------------------------------------------
16
+
17
+ .Output
18
+ ----------------------------------------------------------------------------
19
+ HomepageTest#test_homepage (115 ms warmup)
20
+ process_time: 591 ms
21
+ memory: 3052.90 KB
22
+ objects: 59471
23
+ ----------------------------------------------------------------------------
24
+
25
+
26
+
27
+ Obviously something is very very wrong here. 3052.90 Kb to load my minimal homepage. For Comparison for another site running well I get this for my homepage test.
28
+
29
+ .Default
30
+ ----------------------------------------------------------------------------
31
+ HomepageTest#test_homepage (19 ms warmup)
32
+ process_time: 26 ms
33
+ memory: 298.79 KB
34
+ objects: 1917
35
+ ----------------------------------------------------------------------------
36
+
37
+ that over a factor of ten difference. Lets look at our flat process time file to see if anything pops out at us.
38
+
39
+ .Process time
40
+ ----------------------------------------------------------------------------
41
+ 20.73 0.39 0.12 0.00 0.27 420 Pathname#cleanpath_aggressive
42
+ 17.07 0.14 0.10 0.00 0.04 3186 Pathname#chop_basename
43
+ 6.47 0.06 0.04 0.00 0.02 6571 Kernel#===
44
+ 5.04 0.06 0.03 0.00 0.03 840 Pathname#initialize
45
+ 5.03 0.05 0.03 0.00 0.02 4 ERB::Compiler::ExplicitScanner#scan
46
+ 4.51 0.03 0.03 0.00 0.00 9504 String#==
47
+ 2.94 0.46 0.02 0.00 0.44 1393 String#gsub
48
+ 2.66 0.09 0.02 0.00 0.07 480 Array#each
49
+ 2.46 0.01 0.01 0.00 0.00 3606 Regexp#to_s
50
+ ----------------------------------------------------------------------------
51
+
52
+ Yes indeed we seem to have found the problem. Pathname#cleanpath_aggressive is taking nearly a quarter our process time and Pathname#chop_basename another 17%. From here I do a few more benchmarks to make sure that these processes are slowing down the other pages. They are so now I know what I must do. *If we can get rid of or shorten these processes we can make our pages run much quicker*.
53
+
54
+ Now both of these are main ruby processes so are goal right now is to find out what other process is calling them. Glancing at our Graph file I see that #cleanpath is calling #cleanpath_aggressive. #cleanpath is being called by String#gsub and from there some html template errors. But my page seems to be rendering fine. why would it be calling template errors. I'm decide to check my object flat file to see if I can find any more information.
55
+
56
+ .Objects Created
57
+ ----------------------------------------------------------------------------
58
+ 20.74 34800.00 12324.00 0.00 22476.00 420 Pathname#cleanpath_aggressive
59
+ 16.79 18696.00 9978.00 0.00 8718.00 3186 Pathname#chop_basename
60
+ 11.47 13197.00 6813.00 0.00 6384.00 480 Array#each
61
+ 8.51 41964.00 5059.00 0.00 36905.00 1386 String#gsub
62
+ 6.07 3606.00 3606.00 0.00 0.00 3606 Regexp#to_s
63
+ ----------------------------------------------------------------------------
64
+
65
+ nope nothing new here. Lets look at memory usage
66
+
67
+ .Memory Consuption
68
+ ----------------------------------------------------------------------------
69
+ 40.17 1706.80 1223.70 0.00 483.10 3186 Pathname#chop_basename
70
+ 14.92 454.47 454.47 0.00 0.00 3606 Regexp#to_s
71
+ 7.09 2381.36 215.99 0.00 2165.37 1386 String#gsub
72
+ 5.08 231.19 154.73 0.00 76.46 420 Pathname#prepend_prefix
73
+ 2.34 71.35 71.35 0.00 0.00 1265 String#initialize_copy
74
+ ----------------------------------------------------------------------------
75
+
76
+ Ok so it seems Regexp#to_s is the second costliest process. At this point I try to figure out what could be calling a regular expression cause I very rarely use them. Going over my standard layout I discover at the top.
77
+
78
+
79
+ [source, html]
80
+ ----------------------------------------------------------------------------
81
+ <%if request.env["HTTP_USER_AGENT"].match(/Opera/)%>
82
+ <%= stylesheet_link_tag "opera" %>
83
+ <% end %>
84
+ ----------------------------------------------------------------------------
85
+
86
+ That's wrong. I mistakenly am using a search function for a simple compare function. Lets fix that.
87
+
88
+
89
+ [source, html]
90
+ ----------------------------------------------------------------------------
91
+ <%if request.env["HTTP_USER_AGENT"] =~ /Opera/%>
92
+ <%= stylesheet_link_tag "opera" %>
93
+ <% end %>
94
+ ----------------------------------------------------------------------------
95
+
96
+ I'll now try my test again.
97
+
98
+ ----------------------------------------------------------------------------
99
+ process_time: 75 ms
100
+ memory: 519.95 KB
101
+ objects: 6537
102
+ ----------------------------------------------------------------------------
103
+
104
+ Much better. The problem has been solved. Now I should have realized earlier due to the String#gsub that my problem had to be with reqexp serch function but such knowledge comes with time. Looking through the mass output data is a skill.
105
+
@@ -0,0 +1,185 @@
1
+ == Performance Testing Built into Rails ==
2
+
3
+ As of June 20, 2008 edge rails has had a new type of Unit test geared towards profiling. Of course like most great things, getting it working takes bit of work. The test relies on statistics gathered from the Garbage Collection that isn't readily available from standard compiled ruby. There is a patch located at http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch[http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch]
4
+
5
+ Also the test requires a new version of Ruby-Prof version of 0.6.1. It is not readily available at the moment and can most easily be found as a tarball on github. It's repository is located at git://github.com/jeremy/ruby-prof.git.
6
+
7
+ What follows is a description of how to set up an alternative ruby install to use these features
8
+
9
+ === Compiling the Interpreter ===
10
+
11
+
12
+ [source, shell]
13
+ ----------------------------------------------------------------------------
14
+ [User ~]$ mkdir rubygc
15
+ [User ~]$ wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p111.tar.gz
16
+ [User ~]$ tar -xzvf ruby-1.8.6-p111.tar.gz
17
+ [User ~]$ cd ruby-1.8.6-p111
18
+ [User ruby-1.8.6-p111]$ curl http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch | patch -p0
19
+
20
+ #I like putting my alternative ruby builds in an opt directory, set the prefix to where ever you feel is most comfortable.
21
+
22
+ [User ruby-1.8.6-p111]$ ./configure --prefix=/opt/rubygc
23
+ [User ruby-1.8.6-p111]$ sudo make && make install
24
+ ----------------------------------------------------------------------------
25
+
26
+ Add the following lines in your \~/.profile or \~/.bash\_login for convenience.
27
+
28
+ ----------------------------------------------------------------------------
29
+ alias gcruby='/opt/rubygc/rubygc/bin/ruby'
30
+ alias gcrake='/opt/rubygc/rubygc/bin/rake'
31
+ alias gcgem='/opt/rubygc/rubygc/bin/gem'
32
+ alias gcirb=/opt/rubygc/rubygc/bin/irb'
33
+ alias gcrails='/opt/rubygc/rubygc/bin/rails'
34
+ ----------------------------------------------------------------------------
35
+
36
+ === Installing RubyGems ===
37
+
38
+ Next we need to install rubygems and rails so that we can use the interpreter properly.
39
+
40
+
41
+ [source, shell]
42
+ ----------------------------------------------------------------------------
43
+ [User ~]$ wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz
44
+ [User ~]$ tar -xzvf rubygems-1.2.0.tgz
45
+ [User ~]$ cd rubygems-1.2.0
46
+ [User rubygems-1.2.0]$ gcruby setup.rb
47
+ [User rubygems-1.2.0]$ cd ~
48
+ [User ~]$ gcgem install rake
49
+ [User ~]$ gcgem install mysql
50
+ [User ~]$ gcgem install rails
51
+ ----------------------------------------------------------------------------
52
+
53
+ If installing mysql gem fails ( like it did for me ), you will have to manually install it :
54
+
55
+ [source, shell]
56
+ ----------------------------------------------------------------------------
57
+ [User ~]$ cd /Users/lifo/rubygc/lib/ruby/gems/1.8/gems/mysql-2.7/
58
+ [User mysql-2.7]$ gcruby extconf.rb --with-mysql-config
59
+ [User mysql-2.7]$ make && make install
60
+ ----------------------------------------------------------------------------
61
+
62
+ === Installing Jeremy Kemper's ruby-prof ===
63
+
64
+ We are in the home stretch. All we need now is ruby-proff 0.6.1
65
+
66
+
67
+ [source, shell]
68
+ ----------------------------------------------------------------------------
69
+ [User ~]$ git clone git://github.com/jeremy/ruby-prof.git
70
+ [User ~]$ cd ruby-prof/
71
+ [User ruby-prof (master)]$ gcrake gem
72
+ [User ruby-prof (master)]$ gcgem install pkg/ruby-prof-0.6.1.gem
73
+ ----------------------------------------------------------------------------
74
+
75
+ Finished, go get yourself a power drink!
76
+
77
+ === Ok so I lied, a few more things we need to do ===
78
+
79
+ You have everything we need to start profiling through rails Unit Testing. Unfortunately we are still missing a few files. I'm going to do the next step on a fresh Rails app, but it will work just as well on developmental 2.1 rails application.
80
+
81
+ ==== The Rails App ====
82
+
83
+ First I need to generate a rail app
84
+
85
+ [source, shell]
86
+ ----------------------------------------------------------------------------
87
+ [User ~]$ gcrails profiling_tester -d mysql
88
+ [User ~]$ cd profiling_tester
89
+ [User profiling_tester]$ script/generate scaffold item name:string
90
+ [User profiling_tester]$ gcrake db:create:all
91
+ [User profiling_tester]$ gcrake db:migrate
92
+ [User profiling_tester (master)]$ rm public/index.html
93
+ ----------------------------------------------------------------------------
94
+
95
+ Now I'm going to init it as a git repository and add edge rails as a submodule to it.
96
+
97
+ [source, shell]
98
+ ----------------------------------------------------------------------------
99
+ [User profiling_tester]$ git init
100
+ [User profiling_tester (master)]$ git submodule add git://github.com/rails/rails.git vendor/rails
101
+ ----------------------------------------------------------------------------
102
+
103
+ Finally we want to change config.cache_classes to true in our environment.rb
104
+
105
+ ----------------------------------------------------------------------------
106
+ config.cache_classes = true
107
+ ----------------------------------------------------------------------------
108
+
109
+ If we don't cache classes, then the time Rails spends reloading and compiling our models and controllers will confound our results. Obviously we will try to make our test setup as similar as possible to our production environment.
110
+
111
+ === Generating and Fixing the tests ===
112
+
113
+ Ok next we need to generate the test script.
114
+
115
+ [source, shell]
116
+ ----------------------------------------------------------------------------
117
+ [User profiling_tester (master)]$ script/generate performance_test homepage
118
+ ----------------------------------------------------------------------------
119
+
120
+ This will generate _test/performance/homepage_test.rb_ for you. However, as I have generated the project using Rails 2.1 gem, we'll need to manually generate one more file before we can go ahead.
121
+
122
+ We need to put the following inside _test/performance/test_helper.rb
123
+
124
+
125
+ [source, ruby]
126
+ ----------------------------------------------------------------------------
127
+ require 'test_helper'
128
+ require 'performance_test_help'
129
+ ----------------------------------------------------------------------------
130
+
131
+ Though this depends where you run your tests from and your system config. I myself run my tests from the Application root directory
132
+
133
+ so instead of
134
+
135
+ [source, ruby]
136
+ ----------------------------------------------------------------------------
137
+ require 'test_helper'
138
+
139
+ #I have
140
+
141
+ require 'test/test_helper'
142
+ ----------------------------------------------------------------------------
143
+
144
+ Also I needed to change homepage_test.rb to reflect this also
145
+
146
+ [source, ruby]
147
+ ----------------------------------------------------------------------------
148
+ require 'test/performance/test_helper.rb'
149
+ ----------------------------------------------------------------------------
150
+
151
+ === Testing ===
152
+
153
+ #TODO is there some way to compare multiple request at once like ruby_analyze
154
+
155
+ Now, if we look at the generated performance test ( one we generated using _script/generate performance_test_ ), it'll look something like :
156
+
157
+ [source, ruby]
158
+ ----------------------------------------------------------------------------
159
+ .require 'performance/test_helper'
160
+
161
+ class HomepageTest < ActionController::PerformanceTest
162
+ # Replace this with your real tests.
163
+ def test_homepage
164
+ get '/'
165
+ end
166
+ end
167
+ ----------------------------------------------------------------------------
168
+
169
+
170
+ The format looks very similar to that of an integration test. And guess what, that's what it is. But that doesn't stop you from testing your Model methods. You could very well write something like :
171
+
172
+ [source, ruby]
173
+ ----------------------------------------------------------------------------
174
+ require 'performance/test_helper'
175
+
176
+ class UserModelTest < ActionController::PerformanceTest
177
+ # Replace this with your real tests.
178
+ def test_slow_find
179
+ User.this_takes_shlong_to_run
180
+ end
181
+ end
182
+ ----------------------------------------------------------------------------
183
+
184
+
185
+ Which is very useful way to profile individual processes.
@@ -0,0 +1,27 @@
1
+ == Get Yourself a Game Plan ==
2
+
3
+ You end up dealing with a large amount of data whenever you profile an application. It's crucial to use a rigorous approach to analyzing your application's performance else fail miserably in a vortex of numbers. This leads us to -
4
+
5
+ === The Analysis Process ===
6
+
7
+ I’m going to give an example methodology for conducting your benchmarking and profiling on an application. It is based on your typical scientific method.
8
+
9
+ For something as complex as Benchmarking you need to take any methodology with a grain of salt but there are some basic strictures that you can depend on.
10
+
11
+ Formulate a question you need to answer which is simple, tests the smallest measurable thing possible, and is exact. This is typically the hardest part of the experiment. From there some steps that you should follow are.
12
+
13
+ * Develop a set of variables and processes to measure in order to answer this question!
14
+ * Profile based on the question and variables. Key problems to avoid when designing this experiment are:
15
+ - Confounding: Test one thing at a time, keep everything the same so you don't poison the data with uncontrolled processes.
16
+ - Cross Contamination: Make sure that runs from one test do not harm the other tests.
17
+ - Steady States: If you’re testing long running process. You must take the ramp up time and performance hit into your initial measurements.
18
+ - Sampling Error: Data should perform have a steady variance or range. If you get wild swings or sudden spikes, etc. then you must either account for the reason why or you have a sampling error.
19
+ - Measurement Error: Aka Human error, always go through your calculations at least twice to make sure there are no mathematical errors. .
20
+ * Do a small run of the experiment to verify the design.
21
+ * Use the small run to determine a proper sample size.
22
+ * Run the test.
23
+ * Perform the analysis on the results and determine where to go from there.
24
+
25
+ Note: Even though we are using the typical scientific method; developing a hypothesis is not always useful in terms of profiling.
26
+
27
+