Sunday, July 19, 2009

Forced Refactoring

‹prev | My Chain | next›

Having resolved my abuse of CouchDB yesterday, I need to make sure that I have not broken anything else. All of my "inside", unit level testing is passing, but I never did run my "outside", integration (a.k.a Cucumber) testing. Those Cucumber tests are where I will start today.

That turns out to be a good choice for a starting point. All of the scenarios in the "Browse Meals" feature are now failing. The first one that I will investigate is this failure:
  Scenario: Navigating between meals                                                # features/browse_meals.feature:54
Given a "Pumpkin is a Very Exciting Vegetable" meal enjoyed on December 3, 2008 # features/step_definitions/meal_details.rb:1
And a "Star Wars: The Dinner" meal enjoyed on February 28, 2009 # features/step_definitions/meal_details.rb:1
And a "Focaccia! The Dinner" meal enjoyed on March 3, 2009 # features/step_definitions/meal_details.rb:1
When I view the "Focaccia! The Dinner" meal # features/step_definitions/meal_details.rb:52
Then I should see the "Focaccia! The Dinner" title # features/step_definitions/meal_details.rb:69
When I click "Star Wars: The Dinner" # features/step_definitions/meal_details.rb:65
Could not find link with text or title or id "Star Wars: The Dinner" (Webrat::NotFoundError)
features/browse_meals.feature:61:in `When I click "Star Wars: The Dinner"'
Then I should see the "Star Wars: The Dinner" title # features/step_definitions/meal_details.rb:69
When I click "Pumpkin is a Very Exciting Vegetable" # features/step_definitions/meal_details.rb:65
Then I should see the "Pumpkin is a Very Exciting Vegetable" title # features/step_definitions/meal_details.rb:69
When I click "Star Wars: The Dinner" # features/step_definitions/meal_details.rb:65
Then I should see the "Star Wars: The Dinner" title # features/step_definitions/meal_details.rb:69
When I click "Focaccia! The Dinner" # features/step_definitions/meal_details.rb:65
Then I should see the "Focaccia! The Dinner" title # features/step_definitions/meal_details.rb:69
The page is rendering OK:



The reason for the Cucumber failure is that the links to previous / next meals no longer contain the meal title. The title used to be the second element of the by_date map function. Yesterday, I changed the map function to return the entire meal instead. It should be a simple matter to hook the code up to the new map function. Except...

When I look at the Sinatra action for meals, I notice that I am now pulling back every single meal:
get %r{/meals/(\d+)/(\d+)/(\d+)} do |year, month, day|
data = RestClient.get "#{@@db}/#{year}-#{month}-#{day}"
@meal = JSON.parse(data)

url = "#{@@db}/_design/meals/_view/by_date"
data = RestClient.get url
@meals_by_date = JSON.parse(data)['rows']


@recipes = @meal['menu'].map { |m| wiki_recipe(m) }.compact

@url = request.url

haml :meal
end
That was not so bad when I was only pulling back IDs and titles. It is bad now that I am pulling back everything in each meal. How bad?

I create a "/benchmarking" action to find out how bad:
get '/benchmarking' do
url = "#{@@db}/_design/meals/_view/by_date"
data = RestClient.get url
JSON.parse(data)

""
end
I test this with ApacheBench:
ab -n 100 http://127.0.0.1:4567/benchmarking
...
Requests per second: 4.77 [#/sec] (mean)
I create a "short" map that only includes title and date:
function (doc) {
if (doc['type'] == 'Meal') {
emit(doc['date'], {'title':doc['title'],'date':doc['date']});
}
}
Pointing "/benchmarking" against this new map:
get '/benchmarking' do
url = "#{@@db}/_design/meals/_view/short"
data = RestClient.get url
JSON.parse(data)

""
end
Running ApacheBench again, I find:
ab -n 100 http://127.0.0.1:4567/benchmarking
...
Requests per second: 24.46 [#/sec] (mean)
Five times faster is not bad. Still, I initially benchmarked Sinatra + CouchDB around 10 times faster. For now, I will stick with the "short" view. Replacing "by_date" view with "by_date_short" gets me decent performance. Updating the Haml view to use the "title" attribute from the updated view resolves the problem found by Cucumber:
  Scenario: Navigating between meals
Given a "Pumpkin is a Very Exciting Vegetable" meal enjoyed on December 3, 2008
And a "Star Wars: The Dinner" meal enjoyed on February 28, 2009
And a "Focaccia! The Dinner" meal enjoyed on March 3, 2009
When I view the "Focaccia! The Dinner" meal
Then I should see the "Focaccia! The Dinner" title
When I click "Star Wars: The Dinner"
Then I should see the "Star Wars: The Dinner" title
When I click "Pumpkin is a Very Exciting Vegetable"
Then I should see the "Pumpkin is a Very Exciting Vegetable" title
When I click "Star Wars: The Dinner"
Then I should see the "Star Wars: The Dinner" title
When I click "Focaccia! The Dinner"
Then I should see the "Focaccia! The Dinner" title
(commit)

Up tomorrow: trying to figure out why the remaining 3 scenarios in the "Browse Meals" Cucumber feature are currently failing.

No comments:

Post a Comment