Test all the fucking time
Posted on August 2, 2008
Filed Under Ruby | Leave a Comment
Bryan Liles struck a chord at RubyNation this weekend with his advice for TDD and BDD folks: “How often should we test?” “Test all the fucking time!“. Luckily, it’s easy to do.
Lots of Rails books coming soon
Posted on July 30, 2008
Filed Under Rails | Leave a Comment
The people who market technical books pay attention to the “trends” in technology. The fall of C and C++. The rise of Ruby / Rails. The rise (and fall) of Java. If us technology people “watch the watchers”, we can get a nice warm-and-fuzzy about our current technology choices. For example, look at all the Ruby and Rails books being published in the coming months!
Testing SNMP traps with snmptrapd
Posted on July 6, 2008
Filed Under Rails, UNIX | Leave a Comment
If you’ve never worked with SNMP, then you’re in for a treat. Get ready to party like it’s 1988, with nested authentication models, over-designed protocols, and lots of meaningless numbers. Luckily, if all you need to do is write some ruby code to send SNMP traps, you have the snmp gem to help make things pretty palatable.
So there I was, with my ruby model code happily sending out SNMP traps….or was it? For development (and test and qa) I set up the yaml file to send SNMP traps to localhost (port 162 is the default). I just needed a way to recieve them.
Enter snmptrapd.
Yes! A command line tool to catch the traps and log them the stdout! This turned out to be pretty easy on my MacBookPro - net-snmp is already installed.
The hardest part is setting up the authorization model. Do this: Create a file called snmptrapd.conf in the current directory. Add the line “disableAuthorization yes” to it. Heheh. No need for security - we just want to see them.
Now run the snmptrapd in the foreground, logging everything to stdout:
sudo snmptrapd -f -Lo -c snmptrapd.conf
Done. Now your messages will show up in that console window. This was not as nearly as painful as I expected!
So in the yml file, I will configure the snmp_trap_destination to be localhost for all environments except production. If there is no daemon running, they will quietly be ignored (UDP rocks). If there is one running (debugging qa, development) then they can be logged. Life is good, even when working with a 20 year old protocol.
(and thanks to atlantageek for one of the only blog posts out there about snmp and ruby!)
Beware rendering multiple partials with layouts
Posted on April 27, 2008
Filed Under Rails | Leave a Comment
Want to render more than one partial with the same layout in your page? Beware:
<%= render :partial => ‘p1′, :layout => ‘layouts/p_layout’ %> <%= render :partial => ‘p2′, :layout => ‘layouts/p_layout’ %>
layouts/p_layout.html.erb
<%= yield :top %> <%= yield %> <%= yield :bottom %> <hr/>
_p1.html.erb
<% content_for :top, 'HeaderFor1' %> <% content_for :bottom, 'FooterFor1' %> Content!
_p2.html.erb
<% content_for :top, 'HeaderFor2' %> <% content_for :bottom, 'FooterFor2' %> Content!
Did you expect this?
HeaderFor1 Content! FooterFor1
HeaderFor2 Content! FooterFor2
Nope. You get this:
HeaderFor1 Content! FooterFor1
HeaderFor1HeaderFor2 Content! FooterFor1FooterFor2
The instance variables in the layout object retain their values, even between invocations of render. My workaround (since I’m not sure if some would call this a “feature”)…clear the instance variables at the end of your layout.
<%= yield :top %> <%= yield %> <%= yield :bottom %> <hr/> <% @content_for_top, @content_for_bottom = nil %>
Now it works as I expected.
Rails LOC vs Java LOC
Posted on April 25, 2008
Filed Under Java, Rails | Leave a Comment
At my last client, we wrote a webservice in Java, it had perhaps 30 service calls and 3 endpoints. We worked on it for about 6 months.
$ find services -name *.java -exec wc {} \; | awk '{a+=$1;print a}' |tail -1
64793
At my current client, we are writing a Rails web application. It’s been a living project for almost 2 years.
$ find app -name *.rb -exec wc {} \; | awk '{a+=$1;print a}' |tail -1
5133
$ find lib -name *.rb -exec wc {} \; | awk '{a+=$1;print a}' |tail -1
1141
$ find app -name *.erb -exec wc {} \; | awk '{a+=$1;print a}' |tail -1
3104
Generate mod_rails httpd.conf using cap
Posted on April 23, 2008
Filed Under Apache, Capistrano, Rails, mod_rails | Leave a Comment
With all the discussions around the new mod_rails, I thought I’d post the Apache conf that I came up with. Here’s the strategy: generate httpd.conf using cap, upload it to the server, and graceful restart Apache. This way, you don’t have to get your hands dirty logging into the box to reconfigure anything.
Here’s the erb template for httpd.conf:
#
# Apache httpd.conf
# generated by cap. run by <%= user %> at <%= Time.now %>
#
ServerRoot “<%= current_release %>”
PidFile “<%= current_release %>/tmp/pids/httpd.pid”
LockFile “<%= current_release %>/log/accept.lock”
ServerName localhost
ServerAdmin “me”
Listen <%= web_port %>
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed at a time
# MaxRequestsPerChild: maximum number of requests a server process serves until death
StartServers <%= apache_processes %>
MinSpareServers <%= apache_processes %>
MaxSpareServers <%= apache_processes %>
MaxClients 100
MaxRequestsPerChild 0
ErrorLog “<%= current_release %>/log/apache_error_log”
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg
LogLevel info
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”" combined
CustomLog “<%= current_release %>/log/apache_access_log” combined
#RewriteLog “<%= current_release %>/log/apache_rewrite_log”
# 0-9, 0 = off, 2 and 3 is good for debugging
#RewriteLogLevel 3
ServerTokens Prod
ServerSignature Off
DefaultType text/plain
TypesConfig /usr/local/apache2/conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
<% if behind_https %>
# for envs that sit behind an https load balancer
RequestHeader set X-FORWARDED_PROTO https
<% end %>
# using Passenger (http://www.modrails.com/) to serve Rails
LoadModule passenger_module <%= gem_home %>/passenger-1.0.1/ext/apache2/mod_passenger.so
RailsSpawnServer <%= gem_home %>/passenger-1.0.1/bin/passenger-spawn-server
RailsRuby <%= ruby_binary %>
RailsUserSwitching off
# max number of Rails processes to be spawned at a time
RailsMaxPoolSize <%= max_rails_processes %>
# spawner processes will be killed if idle for 60 minutes
RailsPoolIdleTime 3600
RailsEnv <%= environment %>
RailsAllowModRewrite on
RewriteEngine On
# Check for maintenance file and redirect all requests
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L]
DocumentRoot “<%= current_release %>/public”
<Directory <%= current_release %>/public>
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
# Set the max size for file uploads to 10M
LimitRequestBody 10485760
</Directory>
<Directory />
Options FollowSymLinks
AllowOverride None
Order Deny,Allow
Deny from all
</Directory>
Here is the cap task to generate httpd.conf and upload it to the server:
desc "Generate the apache httpd.conf file from the template"
task :generate_apache_httpd_conf_file, :roles => :app do
require 'erb'
# set up defaults for some vars to go into the template. others are required.
apache_processes = fetch(:www_procs, 2)
max_rails_processes = fetch(:max_rails_procs, 2)
ruby_binary = fetch(:ruby_binary, "ruby")
gem_home = fetch(:gem_home, '/usr/local/lib/ruby/gems/1.8/gems')
behind_https = fetch(:fronted_by_https, false)
template = ERB.new(File.read('config/templates/httpd.conf.erb'), nil, '<>‘)
result = template.result(binding)
put(result, “#{current_release}/httpd.conf”)
end
It runs in an after_update_code task. This way, all server configs are under code control. This is huge! Each deployed environment’s settings are known and tracked - not just loosely keyed on each server. I treat Apache as part of our application - not a service that happens to be running that we deploy into. Using this technique, along with vendor_everything, we’ve minimized our host dependencies.