Commit db3fc55258dfaf5b13982b2395865d599573a473
1 parent
7dd78504
Exists in
master
and in
1 other branch
Problem notices cache is more space effective
Showing
4 changed files
with
83 additions
and
24 deletions
Show diff stats
app/helpers/application_helper.rb
| ... | ... | @@ -47,8 +47,8 @@ module ApplicationHelper |
| 47 | 47 | end |
| 48 | 48 | |
| 49 | 49 | def tally(collection) |
| 50 | - collection.inject({}) do |tallies, value| | |
| 51 | - tallies[value] = (tallies[value] || 0) + 1 | |
| 50 | + collection.values.inject({}) do |tallies, tally| | |
| 51 | + tallies[tally['value']] = tally['count'] | |
| 52 | 52 | tallies |
| 53 | 53 | end |
| 54 | 54 | end | ... | ... |
app/models/problem.rb
| ... | ... | @@ -18,9 +18,9 @@ class Problem |
| 18 | 18 | field :environment |
| 19 | 19 | field :klass |
| 20 | 20 | field :where |
| 21 | - field :user_agents, :type => Array, :default => [] | |
| 22 | - field :messages, :type => Array, :default => [] | |
| 23 | - field :hosts, :type => Array, :default => [] | |
| 21 | + field :user_agents, :type => Hash, :default => {} | |
| 22 | + field :messages, :type => Hash, :default => {} | |
| 23 | + field :hosts, :type => Hash, :default => {} | |
| 24 | 24 | field :comments_count, :type => Integer, :default => 0 |
| 25 | 25 | |
| 26 | 26 | index :app_id |
| ... | ... | @@ -128,19 +128,45 @@ class Problem |
| 128 | 128 | :environment => notice.environment_name, |
| 129 | 129 | :klass => notice.klass, |
| 130 | 130 | :where => notice.where, |
| 131 | - :messages => messages.push(notice.message), | |
| 132 | - :hosts => hosts.push(notice.host), | |
| 133 | - :user_agents => user_agents.push(notice.user_agent_string) | |
| 131 | + :messages => attribute_count_increase(:messages, notice.message), | |
| 132 | + :hosts => attribute_count_increase(:hosts, notice.host), | |
| 133 | + :user_agents => attribute_count_increase(:user_agents, notice.user_agent_string) | |
| 134 | 134 | ) if notice |
| 135 | 135 | update_attributes!(attrs) |
| 136 | 136 | end |
| 137 | 137 | |
| 138 | 138 | def remove_cached_notice_attribures(notice) |
| 139 | - messages.delete_at(messages.index(notice.message)) | |
| 140 | - hosts.delete_at(hosts.index(notice.host)) | |
| 141 | - user_agents.delete_at(user_agents.index(notice.user_agent_string)) | |
| 142 | - save! | |
| 139 | + update_attributes!( | |
| 140 | + :messages => attribute_count_descrease(:messages, notice.message), | |
| 141 | + :hosts => attribute_count_descrease(:hosts, notice.host), | |
| 142 | + :user_agents => attribute_count_descrease(:user_agents, notice.user_agent_string) | |
| 143 | + ) | |
| 143 | 144 | end |
| 144 | 145 | |
| 146 | + private | |
| 147 | + def attribute_count_increase(name, value) | |
| 148 | + counter, index = send(name), attribute_index(value) | |
| 149 | + if counter[index].nil? | |
| 150 | + counter[index] = {'value' => value, 'count' => 1} | |
| 151 | + else | |
| 152 | + counter[index]['count'] += 1 | |
| 153 | + end | |
| 154 | + counter | |
| 155 | + end | |
| 156 | + | |
| 157 | + def attribute_count_descrease(name, value) | |
| 158 | + counter, index = send(name), attribute_index(value) | |
| 159 | + if counter[index]['count'] > 1 | |
| 160 | + counter[index]['count'] -= 1 | |
| 161 | + else | |
| 162 | + counter.delete(index) | |
| 163 | + end | |
| 164 | + counter | |
| 165 | + end | |
| 166 | + | |
| 167 | + def attribute_index(value) | |
| 168 | + Digest::MD5.hexdigest(value.to_s) | |
| 169 | + end | |
| 170 | + | |
| 145 | 171 | end |
| 146 | 172 | ... | ... |
db/migrate/20111102173347_cache_problem_statistics_fix.rb
0 → 100644
| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | +class CacheProblemStatisticsFix < Mongoid::Migration | |
| 2 | + def self.up | |
| 3 | + Problem.all.each do |problem| | |
| 4 | + messages = {} | |
| 5 | + hosts = {} | |
| 6 | + user_agents = {} | |
| 7 | + problem.notices.each do |notice| | |
| 8 | + messages = count_attribute(messages, notice.message) | |
| 9 | + hosts = count_attribute(hosts, notice.host) | |
| 10 | + user_agents = count_attribute(user_agents, notice.user_agent_string) | |
| 11 | + end | |
| 12 | + problem.update_attributes(:messages => messages, :hosts => hosts, :user_agents => user_agents) | |
| 13 | + end | |
| 14 | + end | |
| 15 | + | |
| 16 | + def self.down | |
| 17 | + Problem.all.each do |problem| | |
| 18 | + problem.update_attributes(:messages => {}, :hosts => {}, :user_agents => {}) | |
| 19 | + end | |
| 20 | + end | |
| 21 | + | |
| 22 | + private | |
| 23 | + def self.count_attribute(counter, value) | |
| 24 | + index = Digest::MD5.hexdigest(value.to_s) | |
| 25 | + if counter[index].nil? | |
| 26 | + counter[index] = {'value' => value, 'count' => 1} | |
| 27 | + else | |
| 28 | + counter[index]['count'] += 1 | |
| 29 | + end | |
| 30 | + counter | |
| 31 | + end | |
| 32 | + | |
| 33 | +end | |
| 0 | 34 | \ No newline at end of file | ... | ... |
spec/models/problem_spec.rb
| ... | ... | @@ -205,14 +205,14 @@ describe Problem do |
| 205 | 205 | @err = Factory(:err, :problem => @problem) |
| 206 | 206 | end |
| 207 | 207 | |
| 208 | - it "#messages returns [] by default" do | |
| 209 | - @problem.messages.should == [] | |
| 208 | + it "#messages should be empty by default" do | |
| 209 | + @problem.messages.should == {} | |
| 210 | 210 | end |
| 211 | 211 | |
| 212 | 212 | it "adding a notice adds a string to #messages" do |
| 213 | 213 | lambda { |
| 214 | 214 | Factory(:notice, :err => @err, :message => 'ERR 1') |
| 215 | - }.should change(@problem, :messages).from([]).to(['ERR 1']) | |
| 215 | + }.should change(@problem, :messages).from({}).to({Digest::MD5.hexdigest('ERR 1') => {'value' => 'ERR 1', 'count' => 1}}) | |
| 216 | 216 | end |
| 217 | 217 | |
| 218 | 218 | it "removing a notice removes string from #messages" do |
| ... | ... | @@ -220,7 +220,7 @@ describe Problem do |
| 220 | 220 | lambda { |
| 221 | 221 | @err.notices.first.destroy |
| 222 | 222 | @problem.reload |
| 223 | - }.should change(@problem, :messages).from(['ERR 1']).to([]) | |
| 223 | + }.should change(@problem, :messages).from({Digest::MD5.hexdigest('ERR 1') => {'value' => 'ERR 1', 'count' => 1}}).to({}) | |
| 224 | 224 | end |
| 225 | 225 | end |
| 226 | 226 | |
| ... | ... | @@ -231,14 +231,14 @@ describe Problem do |
| 231 | 231 | @err = Factory(:err, :problem => @problem) |
| 232 | 232 | end |
| 233 | 233 | |
| 234 | - it "#hosts returns [] by default" do | |
| 235 | - @problem.hosts.should == [] | |
| 234 | + it "#hosts should be empty by default" do | |
| 235 | + @problem.hosts.should == {} | |
| 236 | 236 | end |
| 237 | 237 | |
| 238 | 238 | it "adding a notice adds a string to #hosts" do |
| 239 | 239 | lambda { |
| 240 | 240 | Factory(:notice, :err => @err, :request => {'url' => "http://example.com/resource/12"}) |
| 241 | - }.should change(@problem, :hosts).from([]).to(['example.com']) | |
| 241 | + }.should change(@problem, :hosts).from({}).to({Digest::MD5.hexdigest('example.com') => {'value' => 'example.com', 'count' => 1}}) | |
| 242 | 242 | end |
| 243 | 243 | |
| 244 | 244 | it "removing a notice removes string from #hosts" do |
| ... | ... | @@ -246,7 +246,7 @@ describe Problem do |
| 246 | 246 | lambda { |
| 247 | 247 | @err.notices.first.destroy |
| 248 | 248 | @problem.reload |
| 249 | - }.should change(@problem, :hosts).from(['example.com']).to([]) | |
| 249 | + }.should change(@problem, :hosts).from({Digest::MD5.hexdigest('example.com') => {'value' => 'example.com', 'count' => 1}}).to({}) | |
| 250 | 250 | end |
| 251 | 251 | end |
| 252 | 252 | |
| ... | ... | @@ -257,14 +257,14 @@ describe Problem do |
| 257 | 257 | @err = Factory(:err, :problem => @problem) |
| 258 | 258 | end |
| 259 | 259 | |
| 260 | - it "#user_agents returns [] by default" do | |
| 261 | - @problem.user_agents.should == [] | |
| 260 | + it "#user_agents should be empty by default" do | |
| 261 | + @problem.user_agents.should == {} | |
| 262 | 262 | end |
| 263 | 263 | |
| 264 | 264 | it "adding a notice adds a string to #user_agents" do |
| 265 | 265 | lambda { |
| 266 | 266 | Factory(:notice, :err => @err, :request => {'cgi-data' => {'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16'}}) |
| 267 | - }.should change(@problem, :user_agents).from([]).to(['Chrome 10.0.648.204']) | |
| 267 | + }.should change(@problem, :user_agents).from({}).to({Digest::MD5.hexdigest('Chrome 10.0.648.204') => {'value' => 'Chrome 10.0.648.204', 'count' => 1}}) | |
| 268 | 268 | end |
| 269 | 269 | |
| 270 | 270 | it "removing a notice removes string from #user_agents" do |
| ... | ... | @@ -272,7 +272,7 @@ describe Problem do |
| 272 | 272 | lambda { |
| 273 | 273 | @err.notices.first.destroy |
| 274 | 274 | @problem.reload |
| 275 | - }.should change(@problem, :user_agents).from(['Chrome 10.0.648.204']).to([]) | |
| 275 | + }.should change(@problem, :user_agents).from({Digest::MD5.hexdigest('Chrome 10.0.648.204') => {'value' => 'Chrome 10.0.648.204', 'count' => 1}}).to({}) | |
| 276 | 276 | end |
| 277 | 277 | end |
| 278 | 278 | ... | ... |