/ 13.Aug.2008
I am about to release resource_helper plugin. I wrote in while working on my client’s project and it has become invaluable to our team. It attempts to bridge the small gaps between ActiveRecord and ActiveResource and make them quack nearly the same. It also adds some convenience methods which I found myself rewriting for every new ActiveResource. I hope to release it by the end of the day today.
Hehe, my new acronym for god.
The config suggestion I posted earlier works in theory, but I was having some trouble getting it to work from init
What I ended up having to do was add
sleep after some steps of the god init. Multiple sub-config loading from a main config file just wasn’t going to work. I’m am sure there is a better way, but this works for the time being, until I have more free time to work on Unrud itself.
# v.0.0.3
# cobbled by Bryan Taylor http://rubyisbeautiful.com
# god - Start/stop/check Unrud via init
#
# chkconfig: - 85 15
# description: http://god.rubyforge.org/
# processname: god
# config: /etc/god.conf
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -x /usr/bin/god ] || exit 0
RETVAL=0
prog="god"
start() {
# Start daemon only
echo -n $"Starting $prog: "
/usr/bin/god
sleep 5
RETVAL=$?
[ $RETVAL -eq 0 ] && {
touch /var/lock/subsys/$prog
success $"$prog"
}
echo
#load the configs
if [ -e /u/apps/content/current/config/content.god ] ; then
echo -n $"Loading content config: "
/usr/bin/god load /u/apps/content/current/config/content.god
echo -n $"Loading admin config: "
/usr/bin/god load /u/apps/admin/current/config/admin.god
sleep 5
RETVAL=$?
[ $RETVAL -eq 0 ] && {
touch /var/lock/subsys/$prog
success $"$prog"
}
echo
else
RETVAL=1
fi
return $RETVAL
}
stop() {
# Stop daemons.
echo -n $"Shutting down $prog: "
/usr/bin/god quit &
sleep 5
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
return $RETVAL
}
reload() {
echo -n "$reloading $prog config: "
/usr/bin/god load /u/apps/content/current/config/content.god
/usr/bin/god load /u/apps/admin/current/config/admin.god
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
stop
start
;;
status)
/usr/bin/god status
RETVAL=$?
;;
*)
echo "Usage: god {start|stop|reload|restart|status}"
exit 1
;;
esac
exit $RETVAL
Also, I modified the init script a little, as god doesn’t quite behave like a typical *nix daemon.
/ 05.May.2008
Update:
via Twitter from Ivey: updates pushed to rubyforge.
I just checked and all is well; still, follow the advice below to get using git.
If you follow the merb core development, you’ll see that Ivey pushed 0.9.3 gems. Unfortunately it appears temporarily broken via the default install from rubyforge. For now, if you haven’t already hooked up to github and merb, now is the perfect time.
> git clone git://github.com/wycats/merb-core.git
> cd merb-core
> rake install
> cd ..
> git clone git://github.com/wycats/merb-more.git
> cd merb-more
> rake install
/ 03.May.2008
However poor the taste of the author in choosing a name, it is indeed a great way to monitor, nay, control pretty much anything.
I use god on my local dev box (mac) as well to keep all things developery running.
I got the init script from http://ezinearticles.com/?Why-Rails-Developers-Need-God&id=845672 and all the good info from http://god.rubyforge.org/
Handily, a god init script will of course start your mongrels et al when properly configured. Here is how I use a config template for the many gods-mongrels
host = `hostname`
app = "foo"
case
when host =~ /theproductionbox/
ports = %w{ 6400 6401 }
RAILS_ROOT = "/u/apps/#{app}/current"
shared_path = "/u/apps/#{app}/shared"
mongrel_cmd = "/usr/local/bin/ruby /usr/local/bin/mongrel_rails"
pid_dir = "#{shared_path}/pids"
log_file = "#{shared_path}/log/mongrel.log"
uid = 'production_guy'
gid = uid
ENV['RAILS_ENV'] ||= 'production'
rails_env ||= ENV['RAILS_ENV']
http_host = "fancy.productionbox.com"
http_path = "/"
http_code = "200"
when host =~ /somedevbox/
ports = %w{ 6400 }
RAILS_ROOT = "/u/apps/#{app}"
shared_path = "/u/apps/#{app}"
mongrel_cmd = "/usr/local/bin/ruby /usr/local/bin/mongrel_rails"
pid_dir = "#{shared_path}/tmp/pids"
log_file = "#{shared_path}/log/mongrel.log"
uid = 'development_guy'
gid = uid
ENV['RAILS_ENV'] ||= 'development'
rails_env ||= ENV['RAILS_ENV']
http_host = "ratbike.devbox.com"
http_path = "/"
http_code = "200"
end
ports.each do |port|
God.watch do |w|
w.group = app
w.uid = uid
w.gid = gid
w.name = "#{app}-mongrel-#{port}"
w.interval = 30.seconds
w.start = "#{mongrel_cmd} start -d -a 0.0.0.0 -p #{port} -P #{pid_dir}/dispatch.#{port}.pid -e #{rails_env} -c #{RAILS_ROOT} -l #{log_file}"
w.stop = "#{mongrel_cmd} stop -P #{pid_dir}/dispatch.#{port}.pid"
w.start_grace = 30.seconds
w.restart_grace = 30.seconds
w.pid_file = File.join(pid_dir, "dispatch.#{port}.pid")
w.behavior(:clean_pid_file)
w.transition(:init, { true => :up, false => :start }) do |on|
on.condition(:process_running) do |c|
c.running = true
end
end
w.transition([:start, :restart], :up) do |on|
on.condition(:process_running) do |c|
c.running = true
end
on.condition(:tries) do |c|
c.times = 5
c.transition = :start
end
end
w.transition(:up, :start) do |on|
on.condition(:process_exits)
end
w.transition(:up, :restart) do |on|
on.condition(:memory_usage) do |c|
c.interval = 60.seconds
c.above = 57.megabytes
c.times = [4, 5]
end
on.condition(:cpu_usage) do |c|
c.interval = 60.seconds
c.above = 10.percent
c.times = [3, 5]
end
on.condition(:http_response_code) do |c|
c.host = http_host
c.path = http_path
c.code_is_not = http_code
c.timeout = 30.seconds
c.interval = 30.minutes
end
end
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
c.to_state = [:start, :restart]
c.times = 5
c.within = 5.minute
c.transition = :unmonitored
c.retry_in = 10.minutes
c.retry_times = 5
c.retry_within = 2.hours
end
end
end
end
God::Contacts::Email.message_settings = {
:from => 'god@rubyisbeautiful.com'
}
God::Contacts::Email.server_settings = {
#settings
}
God.contact(:email) do |c|
c.name = 'bryan'
c.email = 'bryan@rubyisbeautiful.com'
end
/ 24.Apr.2008
First, I haven’t written in awhile. Like many bloggers that I follow, success in one area diminishes my capacity in other areas. My contracting business is doing very well. More than that however, I don’t like to waste space or mince words on my blog, as you have already noticed. I won’t write unless I have something that I think is worth sharing; I won’t write just to keep a fresh article in the feeds.
I have been doing a lot of debugging – mostly of the needle-in-a-haystack variety. Simultaneously I am working on a new, re-engineered version of the legacy app I am debugging. So I have the opportunity to do some things “right” this time (I didn’t write the legacy app, and the developer who did is AWESOME and a friend. I am not criticizing the code here. What always happens is the problems and business rules become clearer as the project matures, giving rise to an opportunity to craft a better model)
There are of course great plugins to do some of this, and more. I personally have found that in some cases less is more and projects that rely to heavily on 3rd party code may end up paying for at debug time.
Here are some tweaks to errors and whatnot that I use:
1. extend StandardError with a simple to_xml method, for use in ActiveResource and pretty much anywhere:
class StandardError
def to_xml
return <<-ENDOFDOC
<error type='#{self.class.to_s}'>
<message>#{message}</message>
</error>
ENDOFDOC
end
end
1.5. UPDATE: I also added a status method, since I use resources so heavily.
@status=400 #its never the server's fault
attr_accessor :status
and in the custom errors mentioned below, change as needed:
LocalApplication::SomeParameterIsMissing.new.status # => 406
This works nicely for StandardError and any descendent classes that don’t already have a to_xml method. For ActiveRecord:: and some other error classes, there is a to_xml which will override this one.
2. put a general error handler in ApplicationController
def handle_error(err=nil)
begin
if err.nil?
@error = GenericNilError.new("Oops, something happened...")
else
@error = err
end
respond_to do |flavah|
flavah.xml { render :xml => @error.to_xml, status => 500 and return false }
flavah.html # a template for error
end
rescue StandardError => e
# some failsafe that hits a static
render :nothing => true, :status => 500 and return false
end
end
3. use local errors
As in the example above, roll your own errors. Then you respond in customized ways. If you’re not already rescuing different kinds of errors and handling them in unique ways, you may want to explore that.
module LocalApplicationError
class GenericError < StandardError ; end
class ShouldNeverHappenError < StandardError ; end
# etc...
end
4. have an error log
So much better than scrolling through #{RAILS_ENV}.log
err_logger = Logger.new #customize how you want it
[ActiveRecord ActiveResource ActionController].each do |mod|
mod.module_eval <<- ENDOFMONKEY
include LocalApplicationError #why not throw this in there too, see #3 above
@err_logger = err_logger
mattr_reader :err_logger
ENDOFMONKEY
end
5. Use specs so you don’t raise unknown errors!
/ 31.Mar.2008
I recently created merbdoc.com (a.k.a. merbapi) to help the Merb community out. Let me know how if its useful, or how I can improve it. Its brand new, so it might be down for the next day or so.
Here’s a very easy way to change the default render format. Its not necessarily the best way for you. Consider that rendering HTML is hardcoded in the code and it is probably default in the browser/client’s Accept header.
rails/action_pack/lib/action_view/base.rb
when parameter_format.blank? && accept_format != :js
@template_format = :html
For my usage, the best way to change was to add a method to application.rb and call it as a before filter (either by default in application.rb or as needed in each controller)
(updated to a better way)
protected
def set_request_header
xml_string = 'application/xml'
request.instance_eval("@accepts=Mime::Type.lookup('#{xml_string}')")
request.headers['HTTP_ACCEPT'] = xml_string
request.env['HTTP_ACCEPT'] = xml_string
end
it’s not really “playing nice” but it works and is easy to debug and undo
/ 21.Mar.2008
Its Spring Break, which means nothing to me other than that my kids are home from school. Work is difficult. This week instead of carelessly crafter semi-digested thoughts on Ruby et al., I bring you a picture from railsblog

/ 13.Mar.2008
function wo {
cd "/Users/bryan/apps/$1";
}
function devcon {
eval script/console $1;
}
function testcon {
eval "script/console test $1";
}
function prodcon {
eval "script/console production -s $1";
}
function prodcon_live {
eval "script/console production $1";
}
So I get something to go to a certain project I'm working on and use the console quickly.
bash:~> wo merb-core
bash:/Users/bryan/apps/lazy_developer> devcon
>>
It saves a lot of typing.
/ 04.Mar.2008
Well after joining Github recently to work on Merb I did a few things: submitted my first patch, got rejected, and learned a lot about git and merb. xD
Wycats from merb kindly pointed out that the “bug” I had discovered was actually a feature! Indeed it is. Let’s have a look.
working_foo.rb
class WorkingFoo < Application
def index
redirect 'http://merbivore.com'
end
end
failing_foo.rb
class FailingFoo < Application
before :choke
def choke
redirect 'http://merbivore.com'
end
end
So what happens? In retrospect my thoughts were clearly biased by Rails. This application would work in Rails. But that doesn’t mean it is necessarily a smart way to do things. In failing_foo.rb the application is kind of losing control; the filter redirects and the session is abruptly interrupted. The outcome is the same in that the user agent is eventually redirected where they need to go, but it’s not the best way of doing it.
Here is the Merb way
merby_foo.rb
class MerbyFoo < Application
before :awesomeness
def awesomeness
throw :halt, redirect "http://merbivore.com"
end
end
I read about 75% of the Merb code over the weekend to write a patch, and what I came up with was almost the same as the above MerbyFoo (suggested by Wycats), but with a subtle difference. I placed my throw :halt in the redirect method of the Controller mixin with a check to see if it was being called in a filter. Tsk on me. Wycats and the merb way is better, and now I understand it. You would normally expect the before filter that calls redirect to “halt” the before filters, but perhaps not always.
abstract_controller.rb) are flexible. The throw mechanism in filters allows passing a String, Proc, Symbol or nothing. Perhaps the redirect involves something complex:
before :check_em
def check_em
throw :halt, :complex_stuff
end
def complex_stuff
redirect "http://google.com" if user =~ /googler/
redirect "http://yahoo.com" if user =~ /yahooligan/
end
/ 29.Feb.2008
I built the gem on my local machine like this:
git clone git://github.com/wycats/merb-core.git
git clone git://github.com/wycats/merb-more.git
cd merb-core
rake install
cd ../merb-more
rake install
gem list --local merb
*** LOCAL GEMS ***
merb (0.9.0)
merb-action-args (0.9.0)
merb-assets (0.9.0)
merb-builder (0.9.0)
merb-core (0.9.0)
merb-gen (0.9.0)
merb-haml (0.9.0)
merb-mailer (0.9.0)
merb-more (0.9.0)
merb-parts (0.9.0)
merb-test (0.9.0)
/ 29.Feb.2008
I decided to upgrade my installation of merb from the older merb-0.5.x to the new "merb-next" which is re-numbered 0.9.x and available on github.
I knew something was going to finally push me to getting and learning git; so there it is. First thing is to dl and compile of course.
As I found out after a halt in the compile, Leopard needs a SYS V type utility called msgfmt. After a lot of googling and messing around, I found this article by Sean Santry which I found to be most helpful.
NO_MSGFMT=yes make prefix=/usr/local all
/ 24.Feb.2008
I was going to write something in Applescript (after learning Applescript) to open a Safari page in Firefox. I found a somewhat dated example here which I updated slightly, and it works for me YMMV.
tell application "Safari"
activate
set my_URL to the URL in document 1
end tell
-- Convert Unicode Text of my_URL to Plain text
set my_URL to «class ktxt» of ((my_URL as string) as record)
tell application "Firefox"
activate
Get URL my_URL
end tell
quit
/ 23.Feb.2008
I wrote this to facilitate doing things faster in the console. Pretty mindless, but fun to get involved more at rubyforge.
install like your usual plugin (I recommend piston)
svn checkout http://lazy-developer.rubyforge.org/svn/
or
svn checkout svn://rubyforge.org/var/svn/lazy-developer
and you get:
Foo.ff find the first foo
Foo.fl find the last foo
Foo.fa find all foos
Foo.f1(arg) find a foo with this condition
Foo.f(arg) find all foos with this condition
let me know how it goes for you
/ 22.Feb.2008
I saw no visible means of contacting the authors of the micro-tabbed theme, and their svn was down. I consider this to be a pretty crappy bug: they hardcoded their own url into the liquid so links generated map to them. Unintentional or otherwise, its pretty bad. I checked around some other site that use this theme, and they have the same issue. To fix, edit _entry.liquid and replace the default with this:
http://{{ site.host }}{{ article.url }}
micro theme by seaofclouds, and powered with Mephisto Hosting by hostingrails.com