Archive for the ‘coding’ Category

Caching Lessons Learned

Tuesday, January 22nd, 2008

We have a set of bugs with caching:

Versioning:

  • We must version whenever we cache so that we when upgrade, the app uses the updated revision of the cached object
  • In acts_as_cached, there is a version. However, in page caching and fragment caching there is no version number.
  • In page caching, the cached page is saved on disk. Our deployment method overwrites the directory which will refresh this cache.
  • In this case, we should use the same workaround we use in css, icon, and js includes where we define the key as name?<version_number>

Includes:

  • Early on, we used :include in acts_as_cached so that we minimize the number of database calls. However, by over including you can accidentally max out your network. The include is implemented as a big join so if you have m includes where one column has a large amount of data, you will transfer n^m data.
  • We have seen this where we had a column that returns results in the order of 10K, but instead of transfering 60 rows of 10K (600K), we were transferring 10^6 * 10K rows (100MB). Now, that’s a huge difference!

Expiry:

  • We use fragment caching to save rendering in our views. However, the base implementation from rails does not support expiry.
  • Thus, we need to either explicitly expire or use another technique to expire like TTL expire or sweepers

IE6 border bug with vertical scroll

Wednesday, December 12th, 2007

In IE6, we have seen two unusual behaviors solved by position relative.

One is known as the peekaboo bug, where elements to the right of a float div disappear and reappear. You will see this technique used in communities and mymedhelp layout files.

The new one is the border flash bug, where the page renders correctly, but the border disappears when you use the vertical scroll bar to move up and down. This was found in the community members page.

We do not have this bug on tags which uses the exact same partial…so I hypothesize that the vertical scroll bar makes IE6 hit this error path

#community_members {

overflow: hidden;
+ position: relative;

}

Mongrel Misleading Me to Mistakes

Wednesday, December 12th, 2007

I got the error below recently. Good luck debugging the error message below.

The bug was a bad require path. This can also happen with missing gems in your deployed application.

=> Booting Mongrel (use ’script/server webrick’ to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment…
Exiting
c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/rails-2.0.1/lib/commands/ser
vers/mongrel.rb:16: warning: already initialized constant OPTIONS
c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/rails-2.0.1/lib/commands/ser
vers/mongrel.rb:19: undefined method `options’ for []:Array (NoMethodError)
from c:/medhelp/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom
_require.rb:32:in `gem_original_require’
from c:/medhelp/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom
_require.rb:32:in `require’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesupport-2
.0.1/lib/active_support/dependencies.rb:496:in `require’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesupport-2
.0.1/lib/active_support/dependencies.rb:342:in `new_constants_in’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesupport-2
.0.1/lib/active_support/dependencies.rb:496:in `require’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/rails-2.0.1/lib
/commands/server.rb:39
from c:/medhelp/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom
_require.rb:27:in `gem_original_require’
from c:/medhelp/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom
_require.rb:27:in `require’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesupport-2
.0.1/lib/active_support/dependencies.rb:496:in `require’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesupport-2
.0.1/lib/active_support/dependencies.rb:342:in `new_constants_in’
from c:/medhelp/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesupport-2
.0.1/lib/active_support/dependencies.rb:496:in `require’
from ./script/server:3

The fake order of id

Monday, November 5th, 2007

A couple of days ago, I gave Ajay really bad advice. He was changing a piece of code to order the results by created_at instead of ids because ids and my code review boldly stated:

Ids will be chronologically ordered 99.9999% of the time the ids will be chronologically ordered.

While this might be true right now, it is really suboptimal. I realized that when I was thinking about the best way to setup our new database server. It occurred to me that we might want to setup a master-master replication scheme for MySQL server. Once we do that, each MySQL master will have its own range of ids to use when assigning a new automatically generated id to a record being inserted. For example, server A will be able to use ids within the range 1 - 99999 and server B 100000 to 199999

Once that happens, the chronological order of ids will be less continuous and might look like: 324, 100231, 325, 326, 100232,et.

So the lesson I admit to learning is: never sort by IDs when you mean to sort by date. In fact, I can’t think of any reason why you would ever want to sort by ID.

memcache marshaling pain

Monday, October 22nd, 2007

So I was trying to use the memcache increment method during my implementation of the view counter. Whenever I issue a CACHE.incr, CACHE.get starts to fail on that key. I found out what the problem is.

When get is called without specifying the raw argument, it defaults to false, which means that the memcache-client lib will marshal the value passed before sending it to memcache. Then when we issue an incr to the memcached server, it tries to increment the marshaled version which is a binary sequence representing a ruby object (Fixnum in this case) and messes it up.

The solution is to pass the raw parameter to MemCache.set as true, which will prevent the marshaling (later we should call set with a true raw as well) which will give memcached an integer (although treated as string on the ruby side) that it can increment safely.

I created a raw_get, raw_put and raw_incr that can be used together. They are nicely contained in a Cache module (yes, I’m using the same name as the memcache_util.rb module) under our lib folder.