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.

Posted in

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

Posted in , , ,

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>

Posted in ,

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>

Posted in

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!

Posted in , ,

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.

Older posts: 1 ... 23 24 25