FreeBSD, Linux and Timekeeping
Eric Hodel | Fri, 28 Oct 2005 18:12:00 GMT
I’ve been reading a fascinating thread on the freebsd-current mailing list about why MySQL on FreeBSD performs so much less well than Linux.
Apparently MySQL makes many, many calls to the kernel to figure out what time it is so that it can keep track of various things. On Linux this is no problem because they’ve got sloppy timekeeping in their kernel, but FreeBSD is much more accurate.
It eventually lead to a discussion of timers and timing in FreeBSD and how to get the current time faster.
Part of discussion reveals that on the x86 architecture it is incredibly difficult to get the current time in a fast and reliable way.
Rails Functional TestCase
Eric Hodel | Tue, 18 Oct 2005 07:26:00 GMT
Its a shame that Rails doesn’t define its own Test::Unit::TestCase subclasses. I’ve taken that into my own hands. This one puts Test on the front because that’s the Test::Unit way.
require 'test/unit'
def Object.path2class(klassname)
klassname.split('::').inject(Object) { |k,n| k.const_get n }
end
class FunctionalTestCase < Test::Unit::TestCase
def setup
self.class.name =~ /\ATest(.*)\Z/
return unless $1
controller_klass = Object.path2class $1
@controller = controller_klass.new
controller_klass.send(:define_method, :rescue_action) { |e| raise e }
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@deliveries = []
ActionMailer::Base.deliveries = @deliveries
end
def test_stupid
end
end
Easy model urls for Rails
Eric Hodel | Tue, 18 Oct 2005 07:19:00 GMT
One part url params
class Player < ActiveRecord::Base
def url_params
return { :controller => 'players', :action => 'info', :id => username }
end
end
One part url_for override
class ApplicationController < ActionController::Base
def url_for(options, *params)
if options.include? :model then
options = options.delete(:model).url_params.merge options
end
return super(options, *params)
end
end
[Simplified due to some insight from zenspider]
Then just add :model => AR_object to anything that accepts url params:
<ul>
<% @players.each do |player| -%>
<li><%= link_to player.username, :model => player %>
<% end -%>
</ul>
And ba-bam!
<ul>
<li><a href="/players/info/herbert">herbert</a>
<li><a href="/players/info/joseph">joseph</a>
</ul>
Yay! Faster!
Eric Hodel | Thu, 22 Sep 2005 09:52:00 GMT
Bob did some database tuning, and I did some process-size limit tuning, and we nearly cut request time in half:
<samp>2 Days ago: Request Times Summary: Count Avg Std Dev ALL REQUESTS: 628528 0.503 2.632 ThingsController#view: 131293 0.996 3.007 PeopleController#view: 64614 0.519 1.458 RssController#uber: 60804 0.229 1.013 PeopleController#progress: 32300 0.689 1.268 RssController#entries: 31898 0.397 0.943 Yesterday: Request Times Summary: Count Avg Std Dev ALL REQUESTS: 761867 0.273 1.960 ThingsController#view: 148546 0.582 3.060 PeopleController#view: 79980 0.241 0.215 RssController#uber: 68893 0.173 1.591 PeopleController#progress: 57876 0.369 0.186 EntriesController#view: 45982 0.097 0.090</samp>
I love unit tests
Eric Hodel | Sun, 18 Sep 2005 08:01:00 GMT
I just discovered we’ve had a23 broken RSS feeds since February!
Auto-Reconnect for Mogwai Clients
Eric Hodel | Fri, 26 Aug 2005 22:27:00 GMT
I want Mogwai clients to be able to reconnect to the server automatically of the server goes down, so I added a thread that periodically polls the server to see if we’re still registered there.
Here’s what it looks like:
def run
@thread = Thread.start do
loop do
begin
server = Rinda::RingFinger.new BROADCAST_LIST, Mogwai::RING_PORT
@ts = server.lookup_ring_any
register unless registered?
rescue RuntimeError # RingNotFound error (doesn't have its own class)
end
sleep 60
end
end
end
def register
@ts.write @registration, @renewer
end
def registered?
reg = @ts.read [:name, :MogwaiClient, nil, @hostname], 1
return reg[2].__drbref == self.object_id
rescue Rinda::RequestExpiredError
puts "request expired"
return false
end
The second parameter to @ts.read is a timeout value. A read on a TupleSpace will block until there is a matching Tuple to read. Since I’m looking for myself and haven’t yet registered myself, I’ll never match.
I could construct a DRbObject for the template Tuple, but I didn’t think about it until just now, and it would look equally clumsy.
The @renewer is a way of letting the server ensure that the client is still alive.

Articles