Peter Tellgren

Builder of web things.

Adding Dynamic View Paths to ActionMailer in Rails 2.3.11

When I recently rewrote our app at work into a multi tenant app I ran in to the problem of the action_mailer views. Since the app started out it’s life as a single tenant app most of the mails had to be changed but also had to remain the same for the app still there

My first idea was to just configure the template_root of ActionMailer in my new Environment but just after this was done the requirement came that each tenant might want to customize these views. so instead of changing the template_root depending on the tenant I googled around and found a solution for adding the nice view_path method we already have for the ActionController.

The original post can be found here but I thought I would show my implementation below. Basically a compilation of the original poster and the comments given to that post

lib/action_mailer_extensions.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module ActionMailer
  class Base
    class_inheritable_accessor :view_paths

    def self.prepend_view_path(path)
      view_paths.unshift(*path)
    end

    def self.append_view_path(path)
      view_paths.push(*path)
    end

    def view_paths
      self.class.view_paths
    end

    private

    def self.view_paths
      @@view_paths ||= ActionController::Base.view_paths
    end

    def initialize_template_class_without_helpers(assigns)
      ActionView::Base.new(view_paths, assigns, self)
    end

  end
end

I made sure that my lib dir was included in my load paths and then I could mange the view paths as follows

1
ActionMailer::Base.prepend_view_path(RAILS_ROOT + '/app/views/...')

Trouble With ImageMagick on a VPS

This week I was adding a galleries to a rails site that I am working on and for some reason on my production server, each time I tried to upload an image it failed and I got returned a 502 response from my server. The thing was that even though I was looking at my logs I saw no request even being made to the server. I finally got an image to upload and could see in my logs that the action took in excess of one minute to complete which led my Rails worker (unicorn) to time out and return the aforementioned 502 error response. As I went through the call stack I could determine that the bottleneck was ImageMagick and especially the calls to the convert method.

I did some testing and could confirm what I had determined in the logs:

1
2
3
4
$ time utilities/convert 'image.jpg' -resize "x60" -crop "60x60" +repage 'thumb'
real    0m11.602s
user    0m11.414s
sys  0m0.069s

11 seconds to scale and crop an image, that’s just insanly slow!!!

I did some googleing and found rumors that openmp, that is activated by default in ImageMagick and helps to make use of modern CPUs multi core architecture sometimes could cause issues in a virtualized environment wich is exactly what I am running on.

So I went out and got the latest version of the ImageMagick source, compiled it with the —disable-openmp flag and redid the test with this binary:

1
2
3
4
$ time utilities/convert 'image.jpg' -resize "x60" -crop "60x60" +repage 'thumb'
real     0m0.077s
user    0m0.058s
sys     0m0.019s

That’s more like it, don’t you agree. All I know had to do was to install this version on to my server. However as I am running Ubuntu 10.04 so I’d like to keep with the package system. For some reason I was not able to get the 10.04 package of ImageMagick to accept the —disable-openmp flag so, in the end I backported the package from Ubuntu 10.10 instead. please find the steps below:

1. Download the following files:

2. Unpack

1
$ dpkg-source -x imagemagick_6.6.2.6-1ubuntu1.1.dsc

3. Edit the build rules

1
2
$ cd imagemagick-6.6.2.6
$ vim debian/rules

Add the the following line to the ./configure statement on line 25-39. I added mine on line 34.

1
34: —disable-openmp \

4. Add dependencies and build ( I needed these dependencies)

1
2
$ sudo apt-get install liblqr-1-0-dev librsvg2-dev
$ dpkg-buildpackage -b

5. Out with the old, in with the new

1
2
3
4
$ sudo apt-get remove —purge imagemagick
$ sudo dpkg -i libmagickcore3_6.6.2.6-1ubuntu1.1_amd64.deb
$ sudo dpkg -i libmagickwand3_6.6.2.6-1ubuntu1.1_amd64.deb
$ sudo dpkg -i imagemagick_6.6.2.6-1ubuntu1.1_amd64.deb

So there we are, my gallery is now up and running and preforming as should.