Another ticket on Rails Metal loading/requiring issues

Posted by Tim Connor Tue, 28 Apr 2009 21:43:00 GMT

Our (YieldBuild, Inc) use of metal for one of our two highest throughput actions seems to manage to ferret out edge-cases, as I know have another ticket on Rails Metal requiring issues

This one, thankfully doesn’t have any serious performance hits on production (fixing the other one by manually forcing thin to use the right rails handler via a basic config.ru dropped our load by roughly 30%).

There is just a problem with having a dependency on a project constant from within metal, and you have the choice of having development mode choke on the second metal request (due to Rails having unloaded the constant, but not knowing metal needed it reloaded), or forcing a manual require, which will cause a double require. Hopefully none of your models, etc, are non-idempotent on file load (aside from warnings about redefining constants), right?

Problems with mongrel_cluster and Rails 2.3 dispatcher reloading your metal every request 2

Posted by Tim Connor Wed, 15 Apr 2009 23:33:00 GMT

So, once I added a couple Rails metal to our high volume site, my boss complained that our performance took a serious hit. In tracking it down (with strace) we realized that every request was re-requiring each metal, which involves a full load path search. This was not happening on our local script/server started mongrels, but was happening on production for both thin and mongrel_cluster, even after we had gone through every setting and made them match exactly.

We traced it down to the difference of mongrel_cluster versus the script/server. Script/server is going to use the built in, updated for Rails 2.3, mongrel handler. The old stuff called by thin or mongrels started by mongrel_cluster, is going to use the old (“deprecated”) dispatch path, which in a cgi-ish fashion rebuilds the dispatcher and all rack middleware and metal each time, which means re-requiring them all.

So now I am not sure what to do. Do we have to start all of our mongrels with rackup? Do we take the rack mongrel handlers from rails and patch them into wherever? Do I file a bug for Rails that there at least needs to be some documentation, other than just deprecating the method that a stock mongrel will call?

Update I made a ticket for it Also having mongrel start up using the handler in the rails vendorized rack as a config will fix the problem for mongrel. I’m not sure about thin, as that handler seems to be rackup specific?

Update2 Ezra said he’d go with rackup and gave me a monit script for it

Update3 We made a barebone rails config.ru and made thin use that, forcing it down the path of using the built-in rails handler. That dropped our load by 30% roughly, so yeah, this behavior had a significant impact on us.

Updating ARTS', or assert_rjs', :insert_html to work with Rails 2.1-stable 1

Posted by Tim Connor Fri, 19 Sep 2008 01:14:00 GMT

I updated our Rails at work today, and got some test failures, because page.insert_html switched from using new Insertion to Element.insert. So that other people could get the benefit of the quick fix, I found a mirror someone had thrown up on github, forked it, and made my changes. So here is my copy of arts, on github.

The only problem with this is the original githubber for it, Rich Poirier, set the author for the original commits as kevinc, but Kevin Clark’s username on github is actually kevinclark. I don’t think Kevin will mind too much, since he’s not maintaining it, it’s BSD, and he said do whatever with it, on ’boose.

Rails 2.1 and "RangeError: memory address is a recycled object" errors when running tests

Posted by Tim Connor Thu, 24 Jul 2008 22:00:00 GMT

If you are hitting mysterious warnings of the format: “RangeError: 0×19ad692 is recycled object” in your tests, after upgrading to Rails 2.1, it might be due to threading issues. Just commenting out the line


require ‘thread’

in a library at work, that will run without it, quieted the tests, so it’s possible even just requiring it will cause problems in Rails 2.1 (using ruby 1.8.6 p114).

Which is odd, since thread is required at least one place in the AR code itself, and elsewhere in our app. Maybe it’s an interplay of a couple libraries together, such as the non-threadsafe ‘aws/s3’ and thread?

Rails 2 foxy fixtures and named_scope/has_finder closure issues

Posted by Tim Connor Fri, 11 Jul 2008 23:20:00 GMT

If you are using a has_finder (or possibly named_scope, I haven’t confirmed this myself), remember that unless you wrap your condition => in a lambda it is going to be evaluated early – or at least earlier than fixture creation, it seems. At work we had a case where one model had a finder that depended on its belong_to being in a subset of another, basically:


has_finder :all_active, { :conditions => {:status_id => Status.active_ids} }

This work in production, where the ids don’t change, but since we are using the newer fixture approach on this model the ids are created dynamically. Given how fixtures load, the table will probably be populated with the old values, at parse time for that class, then the test will run, and the fixtures will reload, and they will not match anymore.

This is easily fixed, when you realize what is happening:


has_finder :all_active, lambda {|| { :conditions => {:status_id => OtherModel.active_ids} }}

has_many :through and SimplyHelpful form_for 1

Posted by Tim Connor Thu, 15 Mar 2007 19:49:00 GMT

So given how much SimplyHelpful could simplify things by allowing me to have one shared form for both new and edit, all magically handled with a simple "form_for @my_model do |f| ",of course, I jumped at it.

Equally as “of course,” the most complicated piece of the Lost River site that I have been working on is not a simple, single model form, but some variation of a many to many relationship. In fact, it was something best modeled by a “has_many :through” and a case where I definitely wanted the join models easily editable from the creation form.

Now shocking as it may be, how to do this cleanly with the form_for wasn’t immediately apparent to me. In fact, even the reversely eponymous has_many :through blog was slightly misleading (or incorrect?) on this, going through some, of what seem to me to be, unneccessary work-arounds and stating:

has_many :through won’t work with new records, as it needs saved records with actual ids to use in the foreign keys in the join model.

Thankfully I found this post on Rails forum and was able to adapt the collection.build and field_for techniques to my simple_helpful form)for

Report has_many Locations through Conditions and vice versa.

  # GET /reports/new
  def new
    @page_title = 'Creating Report'
    @report = Report.new()
    #Modify the prepoluation to suit your needs
    Location.find(:all).each do |location|
      @report.conditions.build(:location => location)
    end
    render :action => 'edit'
  end

I am using Markaby not erb for my templates.


#edit.mab (used for new and edit action)
error_messages_for ‘report’
form_for(@report) do |form|
label ‘Week of’, :for => ‘report_week_of’
text form.text_field(:week_of)
ul{
@report.conditions.each_with_index do |condition, index|
fields_for “conditions[#{index}]”, condition do |f|
li {
text f.hidden_field(:location_id)
h condition.location.name
br
text f.text_area(:text)
}
end
end
}
text form.submit(‘Save »’)
end

  # POST /reports
  # POST /reports.xml
  def create
    @page_title = 'Creating Report'
    @report = Report.new(params[:report])
    params[:conditions].each_value { |condition| @report.conditions.build(condition)} unless params[:conditions].nil?
...

And wallah, a neat little form_for, with a has_many :through. Of course, the general technique can be modified for other similar results. If anyone knows a way to clean-up or simplify further, please let me know.

A reminder if you do have advice to post: comment moderation is on, and so are AJAX only comments, so there will be no immediate feedback if you comment. I’ll work on throwing something into the template to let you know it’s been successfully submitted one of these days.