content_for in Rails

Tuesday 11/18/2008  –  Category: Uncategorized  –  1 Comment

I'm not sure why I hadn't come across this before, but Rails has a nifty helper called content_for that allows you to insert stuff anywhere in your layout.

A classic use case is inserting a javascript source file that is only used on a specific page.

In your view:

<% content_for :head do %>
  <%= javascript_include_tag 'whatever.js' %>
<% end %>

In your layout:

<head>
  <title>Hello World</title>
  <%= yield :head %>
</head>

apache2-mpm-prefork, apache2-mpm-worker, and PHP5

Tuesday 11/18/2008  –  Category: Uncategorized  –  1 Comment

So I was reading up on Apache MPMs and whether it's better to use worker (threaded) or prefork.

The worker MPM uses multiple child processes. It's multi-threaded within each child, and each thread handles a single connection. Worker is fast and highly scalable and the memory footprint is comparatively low. It's well suited for multiple processors. On the other hand, worker is less tolerant of faulty modules, and a faulty thread can affect all the threads in a child process.

The prefork MPM uses multiple child processes, each child handles one connection at a time. Prefork is well suited for single or double CPU systems, speed is comparable to that of worker, and it's highly tolerant of faulty modules and crashing children - but the memory usage is high, and more traffic leads to greater memory usage.

Since I'm on a Slicehost 256slice, I wanted to try out worker to see if memory/speed performance was improved.

sudo apt-get install apache2-mpm-worker

Performance was a tad bit better--my test Merb app was handling a few requests/sec more with worker than prefork.  However, apache2-mpm-prefork is a required dependency when installing PHP5, so installing apache2-mpm-worker totally removed my PHP installation.  I didn't realize this until I was figured out why Apache was suddenly spitting out PHP pages as downloads.  (Moral of the story: really read the messages when you're prompted to do something)

So why is prefork a dependency?  From  the PHP docs:

PHP is glue. It is the glue used to build cool web applications by sticking dozens of 3rd-party libraries together and making it all appear as one coherent entity through an intuitive and easy to learn language interface. The flexibility and power of PHP relies on the stability and robustness of the underlying platform. It needs a working OS, a working web server and working 3rd-party libraries to glue together. When any of these stop working PHP needs ways to identify the problems and fix them quickly. When you make the underlying framework more complex by not having completely separate execution threads, completely separate memory segments and a strong sandbox for each request to play in, feet of clay are introduced into PHP's system.

If you feel you have to use a threaded MPM, look at a FastCGI configuration where PHP is running in its own memory space.

So, lesson learned.  You're stuck with prefork if you have to serve PHP files with Apache.

Sending email through Gmail SMTP with Merb

Monday 11/3/2008  –  Category: Uncategorized  –  No Comments

I was having email delivery problems while using Postfix (emails were getting caught by spam filters) so I decided to try using Gmail SMTP to send stuff off.

Initially I tried to follow a tutorial like this to get Postfix to relay to Gmail but there was a lot of footwork involved setting up certificates, etc...and I couldn't get it to work at the end.

Finally, after searching around the Merb wiki, I found that it's really a lot more simple:

Gmail SMTP

Install tls mail to enable SSL support (required by Gmail).

$ gem install tlsmail

Then configure Merb Mailer to work with Gmail

in config/init.rb:

Merb::BootLoader.after_app_loads do
  dependency 'tlsmail'

  # Activate SSL Support
  Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)

  # Configure Merb Mailer
  Merb::Mailer.config = {
    :host   => 'smtp.gmail.com',
    :port   => '587',
    :user   => 'user@gmail.com',
    :pass   => 'pass',
    :auth   => :plain
  }
end

Then to send mail:

m = Merb::Mailer.new :to => 'foo@bar.com',
                     :from => 'bar@foo.com',
                     :subject => 'Welcome to whatever!',
                     :text => partial(:sometemplate)
m.deliver!

Server not serving XML correctly?

Wednesday 03/12/2008  –  Category: Uncategorized  –  No Comments

I ran into this issue with a Drupal plugin (FCKeditor) today where an XML file wouldn’t load. it turned out to be a server configuration issue where Apache wasn’t serving XML files as it should, so the ajax request wasn’t processed correctly. To get Apache to serve XML files correctly, add this line to your .htaccess:

AddType text/xml xml

1) Locate your maillog (usually in /var/log)

2) If you cat the file, you’ll get output something like:

    Jan 27 01:19:28 145856-web1 postfix/smtp[8994]: DAA77A74568: to=, relay=none,
delay=388925, status=deferred (connect to noemail.org[82.98.86.165]: Connection refused)

3) we want to check for “status=deferred” or “status=bounced”. we’ll do this with the grep command:

    grep “status=bounced” /var/log/maillog | grep -o -P “to=<(.+?)>” > bounces.log

(you may have to sudo if you’re not logged in as root)

The first half grabs the lines from the log that match the status string.

We just want the email addresses, so we use the pipe operator to pass it on for trimming. Using the -o flag you can get exactly what you want from the matching regex (-P flag). In this case, we see the emails are always surrounded by to=<>”.

Your output (saved to bounces.log) should look something like:

 
to=<adf@asdfa.com>
to=<af@asdf.com>
to=<dfda@fad.COM>
to=<adsfa@df.net>
to=<fd@adf.com>
 

I wanted to get the emails nice and trimmed in an array for use in a Rails app:

 
bounce_array = []
unique_array = []
 
File.open(“PATH/TO/LOGS/bounces.log”, “r”) do |maillog|
  i = 0
  maillog.each_line do |line|
 
     puts “Got email #{i} #{$1}”  if line =~ /to=<(.+?)>/i
     i = i + 1
     bounce_array « $1.to_s
  end   
 
  unique_array = bounce_array.select{|e| bounce_array.index(e) !=
    bounce_array.rindex(e)}.uniq
end
 
unique_array.each do |e|
 puts e
end
 
 Page 14 of 15  « First  ... « 11  12  13  14  15 »