ecin@life

Nov 09

Database views and models in Rails 3

Rails models can have a database view instead of a table, if you so desire. Just follow the pluralize convention:

What won’t work out of the box is preloading associations, since views (at least in Postgres) don’t have primary keys. This means Rails can’t tell rows apart when calling #uniq on an array of results.

Solution: define #hash and #eql? (actually, either one seems to work, but it’s recommended to define both per http://ruby-doc.org/core/classes/Hash.html).

And that’s that. Search.inspect returns “Search(Table doesn’t exist)”, but that’s a minor detail.

Nov 06

Apartment listings should be a bit more interactive.

Apartment listings should be a bit more interactive.

Jun 23

Procrastinating studying for the GRE by writing an app to help me study for the GRE.

Procrastinating studying for the GRE by writing an app to help me study for the GRE.

Jun 21

Jun 04

ObjectSpace::define_finalizer

# So, I just discovered ObjectSpace::define_finalizer

a = "hello"
ObjectSpace.define_finalizer(a, proc { puts "I die!"} )
# Let's eliminate the reference to our string.
a = 1
# And garbage collect!
GC.start
# => I die!

# Pretty neat!

syntax highlighted by Code2HTML, v. 0.9.1

Jun 01

dictionary.rb

Macruby only, since we’re accessing Mac OS X’s dictionary services.

For Macruby 0.6, /System/Library/Frameworks/CoreServices.framework/Frameworks/DictionaryServices.framework/Resources/BridgeSupport/DictionaryServices.bridgesupport needs to be edited.

On line 20, change:

<retval type64='{?=qq}' type='{?=ii}'/>

to

<retval type64='{_CFRange=qq}' type='{_CFRange=ii}'/>

Then you’re good to go:

# Figured out by Craig on the macruby-devel mailing list
framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/DictionaryServices.framework'

word = 'History'
word_len = DCSGetTermRangeInString(nil, word, 0);
result = DCSCopyTextDefinition(nil, word, word_len)

puts "Definition for: #{word}"
puts result

# Or in module form...

module Definable
  def definition
    range = DCSGetTermRangeInString(nil, self.to_s, 0);
    DCSCopyTextDefinition(nil, self.to_s, range)
  end
  def define
    puts self.definition
  end
end

syntax highlighted by Code2HTML, v. 0.9.1

May 18

Maglev and abort_transaction-ing on every request

The code:

Running vanilla Rack::Lobster:

Requests per second: 425.62 [#/sec] (mean) Time per request: 2.350 [ms] (mean) Time per request: 2.350 [ms] (mean, across all concurrent requests)

Running Rack::Lobster and Maglev#abort_transaction-ing with each request:

Requests per second: 404.73 [#/sec] (mean) Time per request: 2.471 [ms] (mean) Time per request: 2.471 [ms] (mean, across all concurrent requests)

These are the best performances from several runs. Difference is pretty much negligible. Certainly varies enough to make the argument that the simplicity makes it worth it.

Aug 21

Rack::Probing

It’s been a fun summer, but with its end comes the wind down of Google’s Summer of Code ‘09 (GSoC). Sounds like an opportunity to talk about Rack::Probe.

Rack::Probe packages a set of Dtrace probes for web applications in an easy-to-use and easy-to-love Rack middleware. Installation is a quick gem install rack-probe away.

As part of my GSoC project, Rack::Probe provides the data that makes profiling and monitoring a web app easier in a way that’s available to most Ruby web frameworks. The standardization that’s occurred on Rack for Ruby web frameworks is extremely helpful.

Let’s give an example a try. For our Rack-enabled app, we’ll be using the following:

Save it as a file somewhere, and run it with rackup filename. If you’d prefer to use your own Rails app, open up config/environment.rb and add in two lines:

Now that our app is running from our virtual law enforcement, let’s spy on it using dtrace to measure our request time. Our D script for doing just that is the following:

Save the script locally, and run it with dtrace -s script_filename. For as long as the script runs, it’ll be gathering data on the distribution of request times for each request that comes in. Feel free to ab -n1000 http://app.uri and go crazy. Control-C to abort the script and have it print out a distribution of the times.

Aside from its portability across frameworks thanks to its implementation as a Rack middleware, Rack::Probe’s benefits come from Dtrace itself. When we’re not actively probing, the overhead amounts to a single method call for each probe in our code, while the D language allows for a number of interesting investigations. For example, expanding our previous example to measure request time per path is as simple as:

While all of this is great and dandy, the catch comes from being limited in your OS choice: Dtrace only runs on Mac OS X, Open/Solaris, and FreeBSD.

Finally, I’d like to make special mention of the fact that all of this wouldn’t be possible without Chris Andrew’s great ruby-dtrace library. Be sure to buy him a beer if you ever get the chance.

Rack::Probe was written as the first stepping stone to Dtracy, which really took the brunt of my efforts this summer. While we wait for that upcoming blog post, feel free to check out Rack::Probe’s source code over at Github.

Aug 19

Proof that sometimes, throwing a small amount of money at something does make it look prettier.

Thanks to Julie Garcia for the logo.

Proof that sometimes, throwing a small amount of money at something does make it look prettier.

Thanks to Julie Garcia for the logo.