<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>Ruby is Awesome - Home</title>
  <id>tag:rubyisawesome.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  
  <link href="http://rubyisawesome.com/" rel="alternate" type="text/html" />
  <updated>2008-11-09T21:17:51Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/ruby_is_awesome" type="application/atom+xml" /><entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2008-11-09:8139</id>
    <published>2008-11-09T21:14:00Z</published>
    <updated>2008-11-09T21:17:51Z</updated>
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/ESiBdFX5z4A/moved-my-blog-to-http-tom-preston-werner-com" rel="alternate" type="text/html" />
    <title>Moved my Blog to http://tom.preston-werner.com</title>
<content type="html">
            &lt;p&gt;I will no longer be posting here at rubyisawesome.com. Check out my new site http://tom.preston-werner.com. You'll also need to update your feed. Hope to see you there!&lt;/p&gt;

&lt;p&gt;Tom&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2008/11/9/moved-my-blog-to-http-tom-preston-werner-com</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-10-13:3263</id>
    <published>2007-10-13T06:40:00Z</published>
    <updated>2007-10-13T06:41:48Z</updated>
    <category term="lazy" />
    <category term="mixin" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/JV-We4Y4yaU/lazy-mixin" rel="alternate" type="text/html" />
    <title>Lazy Mixin</title>
<content type="html">
            &lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;65&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Before you ask--yes, this has a very specific use case and is not&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# generally applicable to the problem of fine-grained lazy evaluation.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# But it does *exactly* what I need it to do. =)&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Allows attributes to be declared as lazy, meaning that they won't be&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# computed until they are asked for. Just mix this module in:&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#   class Foo&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#     include Lazy&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#     ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#   end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# To specify a lazy reader:&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#   lazy_reader :att&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Then, define a method called __bake__ that computes all your lazy&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# attributes:&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#   def __bake__&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#     @att = ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#   end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# That's it! (Tom Preston-Werner: rubyisawesome.com)&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;Lazy&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;ClassMethods&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;lazy_reader&lt;/span&gt;(*args)&lt;tt&gt;
&lt;/tt&gt;      args.each &lt;span class="r"&gt;do&lt;/span&gt; |arg|&lt;tt&gt;
&lt;/tt&gt;        define_method(arg) &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          &lt;span class="pc"&gt;self&lt;/span&gt;.__prebake__&lt;tt&gt;
&lt;/tt&gt;          instance_variable_get((&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; + arg.to_s).intern)&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;__prebake__&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="iv"&gt;@__baked__&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pc"&gt;self&lt;/span&gt;.__bake__&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@__baked__&lt;/span&gt; = &lt;span class="pc"&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.included(base)&lt;tt&gt;
&lt;/tt&gt;    base.extend(&lt;span class="co"&gt;ClassMethods&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# A pedagogical class with a lazy attribute&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Foo&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class="co"&gt;Lazy&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  attr_reader &lt;span class="sy"&gt;:id&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  lazy_reader &lt;span class="sy"&gt;:body&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(id)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@id&lt;/span&gt; = id&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;__bake__&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;__baking__&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@body&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;The 30th fibonacci is &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="pc"&gt;self&lt;/span&gt;.fib(&lt;span class="i"&gt;30&lt;/span&gt;)&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;fib&lt;/span&gt;(n)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="i"&gt;1&lt;/span&gt; &lt;span class="r"&gt;if&lt;/span&gt; n == &lt;span class="i"&gt;0&lt;/span&gt; || n == &lt;span class="i"&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;return&lt;/span&gt; fib(n&lt;span class="i"&gt;-1&lt;/span&gt;) + fib(n&lt;span class="i"&gt;-2&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;t = &lt;span class="co"&gt;Foo&lt;/span&gt;.new(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;abc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;puts t.id      &lt;span class="c"&gt;# =&amp;gt; (immediate) &amp;quot;abc&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;puts t.body    &lt;span class="c"&gt;# =&amp;gt; (short pause) The 30th fibonacci is 1346269&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;puts t.body    &lt;span class="c"&gt;# =&amp;gt; (immediate) The 30th fibonacci is 1346269&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/10/13/lazy-mixin</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-09-11:3187</id>
    <published>2007-09-11T22:52:00Z</published>
    <updated>2007-09-11T22:55:56Z</updated>
    <category term="hash default" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/xhAlowWcDZg/hash-defaults-and-path-of-madness" rel="alternate" type="text/html" />
    <title>Hash Defaults and Path of Madness</title>
<content type="html">
            &lt;p&gt;This is a little story about innocent Ruby mistakes and how they can ruin your day. One of our interns here are Powerset had some code that used default hash values.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;h = {}&lt;tt&gt;
&lt;/tt&gt;h.default = []&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Fair enough. Then the code did this:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;h[&lt;span class="sy"&gt;:foo&lt;/span&gt;] &amp;lt;&amp;lt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="c"&gt;# =&amp;gt; [&amp;quot;foo&amp;quot;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Which happily returns in exactly the expected fashion. We can even check the value to make sure:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;h[&lt;span class="sy"&gt;:foo&lt;/span&gt;] &lt;span class="c"&gt;# =&amp;gt; [&amp;quot;foo&amp;quot;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;But then later on we look more closely at the hash and WTF it's empty!&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;h &lt;span class="c"&gt;# =&amp;gt; {}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Madness! Until you realize that a hash's default value is only used as the return value for a hash lookup of a non-existent key.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;h.default &lt;span class="c"&gt;# =&amp;gt; [&amp;quot;foo&amp;quot;]&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;h[&lt;span class="pc"&gt;nil&lt;/span&gt;] &lt;span class="c"&gt;# =&amp;gt; [&amp;quot;foo&amp;quot;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;And then you can only laugh once you look back at the code that seemed to work and see exactly why it was so deceiving.&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/9/11/hash-defaults-and-path-of-madness</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-09-10:3181</id>
    <published>2007-09-10T20:10:00Z</published>
    <updated>2007-09-10T20:11:45Z</updated>
    <category term="ruby god" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/Jx6W1B7FffM/god-0-4-0-released" rel="alternate" type="text/html" />
    <title>god 0.4.0 released</title>
<content type="html">
            &lt;p&gt;Progress on god is moving along as quick as ever. This release adds a bunch of new features and bug fixes. Most interestingly you'll find several useful new command line functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;god status&lt;/code&gt; prints out the status of each Watch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;god log&lt;/code&gt; shows realtime logs for a specific Watch (even if you don't have god logging to file)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;god load&lt;/code&gt; loads or reloads a config file into a running god instance&lt;/li&gt;
&lt;li&gt;&lt;code&gt;god terminate&lt;/code&gt; stops all Watches and then stops god (useful when testing your setup)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The logging system has been beefed up with proper timestamps and criticality levels. Log messages are more complete overall. You can also get the STDOUT/STDERR of a god-daemonized process written to a log file by specify 'w.log = &amp;lt;log&gt;' in your Watch config.&lt;/p&gt;

&lt;p&gt;If you let god daemonize your process for you, there's no need to provide a stop command. A default killing lambda will take care of gracefully (or not so gracefully if necessary) stopping your god-daemonized process.&lt;/p&gt;

&lt;p&gt;The validity of your config file is checked better than previous versions to point you to the problem area of your config.&lt;/p&gt;

&lt;p&gt;The bug that prevented group control from working has been fixed so you can now start/stop/etc groups of Watches.&lt;/p&gt;

&lt;p&gt;Updated documentation is now available on the website:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://god.rubyforge.org/"&gt;http://god.rubyforge.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WHAT IS GOD?&lt;/p&gt;

&lt;p&gt;God is an easy to configure, easy to extend monitoring framework written in Ruby.&lt;/p&gt;

&lt;p&gt;Keeping your server processes and tasks running should be a simple part of your deployment process. God aims to be the simplest, most powerful monitoring application available.&lt;/p&gt;

&lt;p&gt;DISCLAIMER&lt;/p&gt;

&lt;p&gt;God is still very young, I'd love to get feedback and bug reports, but I do not yet recommend you use it for mission critical tasks. I personally use it in production but then I'm a daring fellow.&lt;/p&gt;

&lt;p&gt;INSTALL&lt;/p&gt;

&lt;p&gt;sudo gem install god&lt;/p&gt;

&lt;p&gt;FEATURES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Config file is written in Ruby&lt;/li&gt;
&lt;li&gt;Easily write your own custom conditions in Ruby&lt;/li&gt;
&lt;li&gt;Supports both poll and event based conditions&lt;/li&gt;
&lt;li&gt;Different poll conditions can have different intervals&lt;/li&gt;
&lt;li&gt;Easily control non-daemonized processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EXAMPLE&lt;/p&gt;

&lt;p&gt;The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I use at gravatar.com to keep the mongrels running:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# file:      gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# run with:  god -c /path/to/gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# This is the actual config file used to keep the mongrels of&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# gravatar.com running.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/var/www/gravatar2/current&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="s"&gt;&lt;span class="dl"&gt;%w{&lt;/span&gt;&lt;span class="k"&gt;8200 8201 8202&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;.each &lt;span class="r"&gt;do&lt;/span&gt; |port|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;God&lt;/span&gt;.watch &lt;span class="r"&gt;do&lt;/span&gt; |w|&lt;tt&gt;
&lt;/tt&gt;    w.name = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gravatar2-mongrel-&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.interval = &lt;span class="i"&gt;30&lt;/span&gt;.seconds &lt;span class="c"&gt;# default&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.start = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::start --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;      -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.stop = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::stop --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;      -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.grace = &lt;span class="i"&gt;10&lt;/span&gt;.seconds&lt;tt&gt;
&lt;/tt&gt;    w.pid_file = &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;log/mongrel.&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.pid&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    w.behavior(&lt;span class="sy"&gt;:clean_pid_file&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    w.start_if &lt;span class="r"&gt;do&lt;/span&gt; |start|&lt;tt&gt;
&lt;/tt&gt;      start.condition(&lt;span class="sy"&gt;:process_running&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;        c.interval = &lt;span class="i"&gt;5&lt;/span&gt;.seconds&lt;tt&gt;
&lt;/tt&gt;        c.running = &lt;span class="pc"&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    w.restart_if &lt;span class="r"&gt;do&lt;/span&gt; |restart|&lt;tt&gt;
&lt;/tt&gt;      restart.condition(&lt;span class="sy"&gt;:memory_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;        c.above = &lt;span class="i"&gt;150&lt;/span&gt;.megabytes&lt;tt&gt;
&lt;/tt&gt;        c.times = [&lt;span class="i"&gt;3&lt;/span&gt;, &lt;span class="i"&gt;5&lt;/span&gt;] &lt;span class="c"&gt;# 3 out of 5 intervals&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;      restart.condition(&lt;span class="sy"&gt;:cpu_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;        c.above = &lt;span class="i"&gt;50&lt;/span&gt;.percent&lt;tt&gt;
&lt;/tt&gt;        c.times = &lt;span class="i"&gt;5&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;DOCS&lt;/p&gt;

&lt;p&gt;Detailed documentation is available at &lt;a href="http://god.rubyforge.org/"&gt;http://god.rubyforge.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CHANGES&lt;/p&gt;

&lt;p&gt;== 0.4.0 / 2007-09-13&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Major Enhancements
&lt;ul&gt;
&lt;li&gt;Add the ability for conditions to override transition state (for exceptional cases)&lt;/li&gt;
&lt;li&gt;Implement dynamic load of config files while god is running (god load &amp;lt;filename&gt;)&lt;/li&gt;
&lt;li&gt;Add ability to save auto-daemonized process output to a log file&lt;/li&gt;
&lt;li&gt;Add robust default stop lambda command for auto-daemonized processes (inspired by _eric)&lt;/li&gt;
&lt;li&gt;Add status command for god binary (shows status of each watch)&lt;/li&gt;
&lt;li&gt;Create proper logger with timestamps&lt;/li&gt;
&lt;li&gt;Add log command to god binary to get real time logs for a specific watch from a running god instance&lt;/li&gt;
&lt;li&gt;Add terminate command for god binary (stop god and all watches)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Minor Enhancements
&lt;ul&gt;
&lt;li&gt;Enforce validity of Watches&lt;/li&gt;
&lt;li&gt;Enforce that God.init is not called after a Watch&lt;/li&gt;
&lt;li&gt;Move pid&lt;em&gt;file&lt;/em&gt;directory creation and validation to God.start&lt;/li&gt;
&lt;li&gt;Remove check for at least one Watch during startup (now that dynamic loading exists)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;New Conditions
&lt;ul&gt;
&lt;li&gt;Tries &amp;lt; PollCondition - triggers after the specified number of tries&lt;/li&gt;
&lt;li&gt;Add :notify&lt;em&gt;when&lt;/em&gt;flapping behavior to check for oscillation [kevinclark]&lt;/li&gt;
&lt;li&gt;Add :degrading_lambda condition. [kevinclark]
It uses a decaying interval (1/2 rate) for 3 cycles before failing.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Bug Fixes
&lt;ul&gt;
&lt;li&gt;Use exit!(0) instead of exit! in god binary to exit with code 0 (instead of default -1)&lt;/li&gt;
&lt;li&gt;Command line group control fixed&lt;/li&gt;
&lt;li&gt;Fix cross-thread return problem&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AUTHORS&lt;/p&gt;

&lt;p&gt;Tom Preston-Werner
Kevin Clark&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/9/10/god-0-4-0-released</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-08-20:3112</id>
    <published>2007-08-20T21:01:00Z</published>
    <updated>2007-08-20T21:02:41Z</updated>
    <category term="powerset ruby interview" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/NNuh2ls08NA/powerset-interview" rel="alternate" type="text/html" />
    <title>Powerset Interview</title>
<content type="html">
            &lt;p&gt;I was recently interviewed by my buddy Ryan Ferrier as part of a series of Powerset employee interviews for Steve Newcomb's blog. I know you think interviews are boring, so here's a little taste of mine to dispel any myths:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;Rumor has it that you listen almost exclusively to techno music, is this
true?&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;My dream is to code in a large, white, egg-shaped room wherein a large,
omnidirectional speaker system is suspended at one locus, and an elaborate,
9 screen, multi-platform computing setup is suspended at the other locus. In
this dream, I am sitting comfortably at the computer locus while thundering
trance emanating from the opposite locus is parabolically focused upon my
exact location. Then I could get some *real* coding done.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Rumor also has it that when listening to said techno music, you get in a
trance-like state for hours on end and transform into a coding machine.
Could you describe this altered state of being for us?&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Remember the guys from "The Matrix" that could look at those screens of
waterfalling green glyphs and see real world objects in them? It's nothing
like that. That's impossible and ridiculous. If you've ever sat zazen and
meditated on some ancient koans, that would be another good example of what
it's not like. It's also not like watching your dog eat peanut butter. I'd
keep going but it would take infinitely long to describe everything that
it's not, so I'll have to stop and leave you mystified by the enigma of it
all.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Continue reading the full &lt;a href="http://p10.hostingprod.com/@www.blognewcomb.com/blog/2007/08/powerset_interview_with_tom_pr.html"&gt;Tom Preston-Werner Interview&lt;/a&gt;.&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/8/20/powerset-interview</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-08-17:3106</id>
    <published>2007-08-17T21:25:00Z</published>
    <updated>2007-08-17T21:25:52Z</updated>
    <category term="god ruby" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/NkVBZ9PJtZc/god-0-3-0-released" rel="alternate" type="text/html" />
    <title>god 0.3.0 released</title>
<content type="html">
            &lt;p&gt;Plenty of big changes and improvements in this release of god. Most noticeable is a simplification of the config file. Sadly, we must say goodbye to the much loved &lt;code&gt;God.meddle&lt;/code&gt; and promote &lt;code&gt;God.watch&lt;/code&gt; to top level. This change allows you to easily load in other god config files and have them work as expected. There's even a &lt;code&gt;God.load&lt;/code&gt; that takes a glob-style file path string and expands it to load multiple files.&lt;/p&gt;

&lt;p&gt;PID file support is now baked in so you don't have to set the &lt;code&gt;pid_file&lt;/code&gt; attribute on conditions anymore. This also allows god to support processes that aren't already daemons. If you don't specify a PID file for the watch, god will auto-daemonize and keep track of your process for you! To use this feature, you must either run as root (pid files will be stored by default in /var/run/god) or set the &lt;code&gt;pid_file_directory&lt;/code&gt; attribute in a &lt;code&gt;God.init&lt;/code&gt; block (see docs).&lt;/p&gt;

&lt;p&gt;For anyone that had problems installing the 0.2.0 release because of the events system not compiling, god 0.3.0 will now allow you to install without event support. Most systems are capable of supporting events, but it requires some dedication to get the headers in place and make sure your kernel is new enough. To determine if your god installation has event support you can run "sudo god -V" (this MUST be run as root on Linux, as netlink connector requires root permissions).&lt;/p&gt;

&lt;p&gt;Using the god binary you can now control your watches from the command line. You can start/stop/restart/monitor/unmonitor watches at your demand.&lt;/p&gt;

&lt;p&gt;New watch attributes now available:
  pid_file: sets the watch process' PID file location
  uid/gid: start processes as someone else (requires root access)
  group: assign a watch to a group (to control them all at once)
  autostart: prevent auto start on god start if false&lt;/p&gt;

&lt;p&gt;Updated documentation is now available on the website:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://god.rubyforge.org/"&gt;http://god.rubyforge.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WHAT IS GOD?&lt;/p&gt;

&lt;p&gt;God is an easy to configure, easy to extend monitoring framework written in Ruby.&lt;/p&gt;

&lt;p&gt;Keeping your server processes and tasks running should be a simple part of your deployment process. God aims to be the simplest, most powerful monitoring application available.&lt;/p&gt;

&lt;p&gt;DISCLAIMER&lt;/p&gt;

&lt;p&gt;God is still very young, I'd love to get feedback and bug reports, but I do not yet recommend you use it for mission critical tasks. I personally use it in production but then I'm a daring fellow.&lt;/p&gt;

&lt;p&gt;INSTALL&lt;/p&gt;

&lt;p&gt;sudo gem install god&lt;/p&gt;

&lt;p&gt;FEATURES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Config file is written in Ruby&lt;/li&gt;
&lt;li&gt;Easily write your own custom conditions in Ruby&lt;/li&gt;
&lt;li&gt;Supports both poll and event based conditions&lt;/li&gt;
&lt;li&gt;Different poll conditions can have different intervals&lt;/li&gt;
&lt;li&gt;Easily control non-daemonized processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EXAMPLE&lt;/p&gt;

&lt;p&gt;The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I use at gravatar.com to keep the mongrels running:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# file:      gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# run with:  god -c /path/to/gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# This is the actual config file used to keep the mongrels of&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# gravatar.com running.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/var/www/gravatar2/current&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="s"&gt;&lt;span class="dl"&gt;%w{&lt;/span&gt;&lt;span class="k"&gt;8200 8201 8202&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;.each &lt;span class="r"&gt;do&lt;/span&gt; |port|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;God&lt;/span&gt;.watch &lt;span class="r"&gt;do&lt;/span&gt; |w|&lt;tt&gt;
&lt;/tt&gt;    w.name = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gravatar2-mongrel-&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.interval = &lt;span class="i"&gt;30&lt;/span&gt;.seconds &lt;span class="c"&gt;# default&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.start = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::start --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;      -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.stop = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::stop --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;      -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    w.grace = &lt;span class="i"&gt;10&lt;/span&gt;.seconds&lt;tt&gt;
&lt;/tt&gt;    w.pid_file = &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;log/mongrel.&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.pid&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    w.behavior(&lt;span class="sy"&gt;:clean_pid_file&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    w.start_if &lt;span class="r"&gt;do&lt;/span&gt; |start|&lt;tt&gt;
&lt;/tt&gt;      start.condition(&lt;span class="sy"&gt;:process_running&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;        c.interval = &lt;span class="i"&gt;5&lt;/span&gt;.seconds&lt;tt&gt;
&lt;/tt&gt;        c.running = &lt;span class="pc"&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    w.restart_if &lt;span class="r"&gt;do&lt;/span&gt; |restart|&lt;tt&gt;
&lt;/tt&gt;      restart.condition(&lt;span class="sy"&gt;:memory_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;        c.above = &lt;span class="i"&gt;150&lt;/span&gt;.megabytes&lt;tt&gt;
&lt;/tt&gt;        c.times = [&lt;span class="i"&gt;3&lt;/span&gt;, &lt;span class="i"&gt;5&lt;/span&gt;] &lt;span class="c"&gt;# 3 out of 5 intervals&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;      restart.condition(&lt;span class="sy"&gt;:cpu_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;        c.above = &lt;span class="i"&gt;50&lt;/span&gt;.percent&lt;tt&gt;
&lt;/tt&gt;        c.times = &lt;span class="i"&gt;5&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;DOCS&lt;/p&gt;

&lt;p&gt;Detailed documentation is available at &lt;a href="http://god.rubyforge.org/"&gt;http://god.rubyforge.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CHANGES&lt;/p&gt;

&lt;p&gt;== 0.3.0 / 2007-08-17&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix netlink header problem on Ubuntu Edgy [Dan Sully]&lt;/li&gt;
&lt;li&gt;Add uid/gid setting for processes [kevinclark]&lt;/li&gt;
&lt;li&gt;Add autostart flag for watches so they don't necessarily startup with god [kevinclark]&lt;/li&gt;
&lt;li&gt;Change command line call options for god binary to accommodate watch start/stop functionality&lt;/li&gt;
&lt;li&gt;Add individual start/stop/restart grace periods for finer grained control&lt;/li&gt;
&lt;li&gt;Change default DRb port to 17165 ('god'.to_i(32))&lt;/li&gt;
&lt;li&gt;Implement command line control to start/restart/stop/monitor/unmonitor watches/groups by name&lt;/li&gt;
&lt;li&gt;Watches can now belong to a group that can be controlled as a whole&lt;/li&gt;
&lt;li&gt;Allow god to be installed (sans events) on systems that don't support events&lt;/li&gt;
&lt;li&gt;Daemonize and handle PID files for non-daemonizing scripts [kevinclark]&lt;/li&gt;
&lt;li&gt;Fix simple mode lifecycle gap&lt;/li&gt;
&lt;li&gt;Remove necessity to specify pid_file for conditions&lt;/li&gt;
&lt;li&gt;Change config file to use God.init and God.watch directly instead of God.meddle block&lt;/li&gt;
&lt;li&gt;Move god binary command logic to main library&lt;/li&gt;
&lt;li&gt;Enhance god binary with better reporting&lt;/li&gt;
&lt;li&gt;Fix synchronization bug in Timer (reported by Srini Panguluri)&lt;/li&gt;
&lt;li&gt;Add Lambda condition for easy custom conditions [Mike Mintz]&lt;/li&gt;
&lt;li&gt;Add sugar for numerics (seconds, minutes, kilobytes, megabytes, percent, etc)&lt;/li&gt;
&lt;li&gt;Add optional PID and log file generation to god binary for daemon mode&lt;/li&gt;
&lt;li&gt;Add God.load to do glob enabled loading&lt;/li&gt;
&lt;li&gt;Add -V option to god binary for detailed version/build info&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AUTHORS&lt;/p&gt;

&lt;p&gt;Tom Preston-Werner&lt;br /&gt;
Kevin Clark&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/8/17/god-0-3-0-released</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-07-19:3048</id>
    <published>2007-07-19T22:16:00Z</published>
    <updated>2007-07-19T22:17:01Z</updated>
    <category term="god ruby monit" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/LjPbcUDvsUg/god-0-2-0-released" rel="alternate" type="text/html" />
    <title>god 0.2.0 released</title>
<content type="html">
            &lt;p&gt;A lot of work has gone into god since the last release. Say goodbye to polling for process status--support for event based conditions via kqueue/netlink has been added (thanks Kevin Clark)! Only a few events are currently supported (most prominently process exit), but the way is now open for the addition of other events. A new, advanced syntax is available (in addition to the familiar simple syntax) that gives you full power over the new state based lifecycle of your Watches. Updated documentation is available on the website:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://god.rubyforge.org/"&gt;http://god.rubyforge.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WHAT IS GOD?&lt;/p&gt;

&lt;p&gt;God is an easy to configure, easy to extend monitoring framework written in Ruby.&lt;/p&gt;

&lt;p&gt;Keeping your server processes and tasks running should be a simple part of your deployment process. God aims to be the simplest, most powerful monitoring application available.&lt;/p&gt;

&lt;p&gt;DISCLAIMER&lt;/p&gt;

&lt;p&gt;God is still very young, I'd love to get feedback and bug reports, but I do not yet recommend you use it for mission critical tasks. I personally use it in production but then I'm a daring fellow.&lt;/p&gt;

&lt;p&gt;INSTALL&lt;/p&gt;

&lt;p&gt;sudo gem install god&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;note: currently tested only on Redhat Linux and Darwin (won't work on Windows)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FEATURES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Config file is written in Ruby&lt;/li&gt;
&lt;li&gt;Easily write your own custom conditions in Ruby&lt;/li&gt;
&lt;li&gt;Supports both poll and event based conditions&lt;/li&gt;
&lt;li&gt;Different poll conditions can have different intervals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EXAMPLE&lt;/p&gt;

&lt;p&gt;The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I use at gravatar.com to keep the mongrels running:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# file:      gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# run with:  god start -c /path/to/gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# This is the actual config file used to keep the mongrels of&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# gravatar.com running.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/var/www/gravatar2/current&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;God&lt;/span&gt;.meddle &lt;span class="r"&gt;do&lt;/span&gt; |god|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="s"&gt;&lt;span class="dl"&gt;%w{&lt;/span&gt;&lt;span class="k"&gt;8200 8201 8202&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;.each &lt;span class="r"&gt;do&lt;/span&gt; |port|&lt;tt&gt;
&lt;/tt&gt;    god.watch &lt;span class="r"&gt;do&lt;/span&gt; |w|&lt;tt&gt;
&lt;/tt&gt;      w.name = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gravatar2-mongrel-&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.interval = &lt;span class="i"&gt;30&lt;/span&gt; &lt;span class="c"&gt;# seconds default&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.start = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::start --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;        -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.stop = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::stop --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;        -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.grace = &lt;span class="i"&gt;10&lt;/span&gt; &lt;span class="c"&gt;# seconds&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      pid_file = &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;log/mongrel.&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.pid&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      w.behavior(&lt;span class="sy"&gt;:clean_pid_file&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |b|&lt;tt&gt;
&lt;/tt&gt;        b.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;      w.start_if &lt;span class="r"&gt;do&lt;/span&gt; |start|&lt;tt&gt;
&lt;/tt&gt;        start.condition(&lt;span class="sy"&gt;:process_running&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;          c.interval = &lt;span class="i"&gt;5&lt;/span&gt; &lt;span class="c"&gt;# seconds&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.running = &lt;span class="pc"&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      w.restart_if &lt;span class="r"&gt;do&lt;/span&gt; |restart|&lt;tt&gt;
&lt;/tt&gt;        restart.condition(&lt;span class="sy"&gt;:memory_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;          c.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;          c.above = (&lt;span class="i"&gt;150&lt;/span&gt; * &lt;span class="i"&gt;1024&lt;/span&gt;) &lt;span class="c"&gt;# 150mb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.times = [&lt;span class="i"&gt;3&lt;/span&gt;, &lt;span class="i"&gt;5&lt;/span&gt;] &lt;span class="c"&gt;# 3 out of 5 intervals&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;        restart.condition(&lt;span class="sy"&gt;:cpu_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;          c.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;          c.above = &lt;span class="i"&gt;50&lt;/span&gt; &lt;span class="c"&gt;# percent&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.times = &lt;span class="i"&gt;5&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;DOCS&lt;/p&gt;

&lt;p&gt;Detailed documentation is available at &lt;a href="http://god.rubyforge.org/"&gt;http://god.rubyforge.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CHANGES&lt;/p&gt;

&lt;p&gt;== 0.2.0 / 2007-07-18&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewrote innards to use a state and event based lifecycle&lt;/li&gt;
&lt;li&gt;Basic support for events via kqueue (bsd/darwin) and netlink/pec (linux) [kevinclark]&lt;/li&gt;
&lt;li&gt;Added advanced syntax (simple syntax calls advanced api underneath)&lt;/li&gt;
&lt;li&gt;Condition returns have changed meaning. With simple syntax, a true return activates block&lt;/li&gt;
&lt;li&gt;Updated http://god.rubyforge.org with updated simple config and new advanced config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AUTHORS&lt;/p&gt;

&lt;p&gt;Tom Preston-Werner&lt;br /&gt;
Kevin Clark&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/7/19/god-0-2-0-released</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-07-10:3026</id>
    <published>2007-07-10T18:47:00Z</published>
    <updated>2007-07-10T18:47:33Z</updated>
    <category term="mysql" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/TOjUY0cexKk/mysql-secrets-g-instead-of" rel="alternate" type="text/html" />
    <title>MySQL secrets: \G instead of ;</title>
<content type="html">
            &lt;p&gt;I'm a MySQL command line junkie. Even when I have a GUI frontend installed, I always find myself typing &lt;code&gt;mysql&lt;/code&gt; into terminal when I need to peek inside the database. As such, one trick that has changed my life for the better is the \G statement terminator. Normally when you execute a query you get something like:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;mysql&amp;gt; select * from queries order by id desc limit 1;&lt;tt&gt;
&lt;/tt&gt;+-----+------------------------------------+--------------+------------+------------+&lt;tt&gt;
&lt;/tt&gt;| id  | query                              | query_set_id | created_at | updated_at |&lt;tt&gt;
&lt;/tt&gt;+-----+------------------------------------+--------------+------------+------------+&lt;tt&gt;
&lt;/tt&gt;| 969 | when a stranger calls sound boards |          103 | 2007-07-09 | 2007-07-09 | &lt;tt&gt;
&lt;/tt&gt;+-----+------------------------------------+--------------+------------+------------+&lt;tt&gt;
&lt;/tt&gt;1 row in set (0.00 sec)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;That's ok, but for tables with more than a few columns you get a nasty bunch of badly wrapped output that's essentially impossible to decipher. If you replace the terminating semicolon with \G, you'll get this output instead:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;mysql&amp;gt; select * from queries order by id desc limit 1 \G&lt;tt&gt;
&lt;/tt&gt;*************************** 1. row ***************************&lt;tt&gt;
&lt;/tt&gt;          id: 969&lt;tt&gt;
&lt;/tt&gt;       query: when a stranger calls sound boards&lt;tt&gt;
&lt;/tt&gt;query_set_id: 103&lt;tt&gt;
&lt;/tt&gt;  created_at: 2007-07-09&lt;tt&gt;
&lt;/tt&gt;  updated_at: 2007-07-09&lt;tt&gt;
&lt;/tt&gt;1 row in set (0.00 sec)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Aaaaaaaaah! Now we're talking. You can even copy this output and paste it right into a YAML fixture in your rails app (with a little fixing of the indentation)!&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/7/10/mysql-secrets-g-instead-of</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-07-07:3047</id>
    <published>2007-07-07T22:12:00Z</published>
    <updated>2007-07-19T22:13:25Z</updated>
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/nvo0Gue74-8/god-0-1-0-released" rel="alternate" type="text/html" />
    <title>god 0.1.0 released</title>
<content type="html">
            &lt;p&gt;I'm proud to announce the initial public release of god!&lt;/p&gt;

&lt;p&gt;http://god.rubyforge.org/&lt;/p&gt;

&lt;p&gt;WHAT IS GOD?&lt;/p&gt;

&lt;p&gt;God is an easy to configure, easy to extend monitoring framework written in Ruby.&lt;/p&gt;

&lt;p&gt;Keeping your server processes and tasks running should be a simple part of your deployment process. God aims to be the simplest, most powerful monitoring application available.&lt;/p&gt;

&lt;p&gt;DISCLAIMER&lt;/p&gt;

&lt;p&gt;God is still very young, I'd love to get feedback and bug reports, but I do not yet recommend you use it for mission critical tasks. I personally use it in production but then I'm a daring fellow.&lt;/p&gt;

&lt;p&gt;INSTALL&lt;/p&gt;

&lt;p&gt;sudo gem install god&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;note: currently tested only on Redhat Linux and Darwin (won't work on Windows)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FEATURES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Config file is written in Ruby&lt;/li&gt;
&lt;li&gt;Easily write your own custom conditions in Ruby&lt;/li&gt;
&lt;li&gt;Supports both poll and event based conditions&lt;/li&gt;
&lt;li&gt;Different poll conditions can have different intervals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EXAMPLE&lt;/p&gt;

&lt;p&gt;The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I use at gravatar.com to keep the mongrels running:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# file:      gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# run with:  god start -c /path/to/gravatar.god&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;#&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# This is the actual config file used to keep the mongrels of&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# gravatar.com running.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/var/www/gravatar2/current&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;God&lt;/span&gt;.meddle &lt;span class="r"&gt;do&lt;/span&gt; |god|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="s"&gt;&lt;span class="dl"&gt;%w{&lt;/span&gt;&lt;span class="k"&gt;8200 8201 8202&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;.each &lt;span class="r"&gt;do&lt;/span&gt; |port|&lt;tt&gt;
&lt;/tt&gt;    god.watch &lt;span class="r"&gt;do&lt;/span&gt; |w|&lt;tt&gt;
&lt;/tt&gt;      w.name = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gravatar2-mongrel-&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.interval = &lt;span class="i"&gt;30&lt;/span&gt; &lt;span class="c"&gt;# seconds&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.start = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::start --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;        -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.stop = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mongrel_rails cluster::stop --only &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="ch"&gt;\&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="k"&gt;        -C &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/config/mongrel_cluster.yml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      w.grace = &lt;span class="i"&gt;10&lt;/span&gt; &lt;span class="c"&gt;# seconds&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      pid_file = &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;log/mongrel.&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;port&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.pid&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      w.behavior(&lt;span class="sy"&gt;:clean_pid_file&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |b|&lt;tt&gt;
&lt;/tt&gt;        b.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;      w.start_if &lt;span class="r"&gt;do&lt;/span&gt; |start|&lt;tt&gt;
&lt;/tt&gt;        start.condition(&lt;span class="sy"&gt;:process_not_running&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;          c.interval = &lt;span class="i"&gt;5&lt;/span&gt; &lt;span class="c"&gt;# seconds&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      w.restart_if &lt;span class="r"&gt;do&lt;/span&gt; |restart|&lt;tt&gt;
&lt;/tt&gt;        restart.condition(&lt;span class="sy"&gt;:memory_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;          c.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;          c.above = (&lt;span class="i"&gt;150&lt;/span&gt; * &lt;span class="i"&gt;1024&lt;/span&gt;) &lt;span class="c"&gt;# 150mb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.times = [&lt;span class="i"&gt;3&lt;/span&gt;, &lt;span class="i"&gt;5&lt;/span&gt;] &lt;span class="c"&gt;# 3 out of 5 intervals&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;        restart.condition(&lt;span class="sy"&gt;:cpu_usage&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;          c.pid_file = pid_file&lt;tt&gt;
&lt;/tt&gt;          c.above = &lt;span class="i"&gt;50&lt;/span&gt; &lt;span class="c"&gt;# percent&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          c.times = &lt;span class="i"&gt;5&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;DOCS&lt;/p&gt;

&lt;p&gt;Detailed documentation is available at http://god.rubyforge.org/&lt;/p&gt;

&lt;p&gt;CHANGES&lt;/p&gt;

&lt;p&gt;== 0.1.0 / 2007-07-07&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 major enhancement
&lt;ul&gt;
&lt;li&gt;Birthday!&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AUTHOR&lt;/p&gt;

&lt;p&gt;Tom Preston-Werner&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/7/7/god-0-1-0-released</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-06-26:2967</id>
    <published>2007-06-26T23:48:00Z</published>
    <updated>2007-06-26T23:50:16Z</updated>
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/jCTW2HUF6Sk/disable-stdout-for-tests" rel="alternate" type="text/html" />
    <title>Disable STDOUT for tests</title>
<content type="html">
            &lt;p&gt;I write a lot of command line tools at &lt;a href="http://powerset.com/"&gt;Powerset&lt;/a&gt;, so I need to output status messages to the console while code is executing. Big deal, right? Well, it becomes a big deal once you run your test suite and you've got two hundred lines of status messages mixed in with the normal test output. I don't need to see console output during my tests. Here's a little method that will disable output to STDOUT for the duration of the block that it's given:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;no_stdout&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; old_stdout = &lt;span class="gv"&gt;$stdout&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span class="gv"&gt;$stdout&lt;/span&gt;.reopen(&lt;span class="co"&gt;File&lt;/span&gt;.open((&lt;span class="co"&gt;PLATFORM&lt;/span&gt; =~ &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;mswin&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; ? &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;NUL&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/dev/null&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;), &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt; &lt;span class="r"&gt;yield&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span class="gv"&gt;$stdout&lt;/span&gt; = old_stdout&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;In your test, you'd call it like this:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;test_whatever&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  no_stdout &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;no one will ever see this&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This technique also works well for 3rd party libraries that might send some output to STDOUT that you don't want to see.&lt;/p&gt;

&lt;p&gt;Sometimes, when I have a lot of output I need to do, I'll wrap &lt;code&gt;puts&lt;/code&gt; and &lt;code&gt;print&lt;/code&gt; in my own methods and call those from my code. This also allows me to add a &lt;code&gt;$stdout.flush&lt;/code&gt; to make sure that the output is sent to the terminal immediately (some systems will buffer output up to a certain size, making those little progress meters useless):&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;out&lt;/span&gt;(text = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    print text&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="gv"&gt;$stdout&lt;/span&gt;.flush&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;outs&lt;/span&gt;(text = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    out(text + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now instead of using the &lt;code&gt;no_stdout&lt;/code&gt; method from above, I can simply redefine those methods to do nothing and all my output vanishes!&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;out&lt;/span&gt;(x); &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;outs&lt;/span&gt;(x); &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Don't settle for crufty test output. We have the technology!&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/6/26/disable-stdout-for-tests</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-05-24:2869</id>
    <published>2007-05-24T17:57:00Z</published>
    <updated>2007-05-24T17:59:21Z</updated>
    <category term="erlang" />
    <category term="fuzed" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/784RCQEuLXk/fuzed-rails-on-yaws" rel="alternate" type="text/html" />
    <title>Fuzed (Rails on YAWS)</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://kirindave.tumblr.com/"&gt;Dave Fayram&lt;/a&gt; and I started working on a new deployment option for Rails last week and had something to show off at RailsConf. If you're into Erlang, you'll immediately see the awesomeness that can come out of putting a connection pool of Rails instances (just Rails, no mongrels) behind YAWS, the pure Erlang web server.&lt;/p&gt;

&lt;p&gt;We showed this sucker off at RejectConf and &lt;a href="http://peepcode.com/"&gt;Geoff Grosenbach&lt;/a&gt; was kind enough to record it, so here's the audio for your pre-alpha enjoyment!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://paranode.com/~topfunky/audio/2007/uncut/STE-022-rej-fuzed.mp3"&gt;Fuzed @ RejectConf Audio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll be seeing much much more about this project in the coming weeks. It's gonna be sweet!&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/5/24/fuzed-rails-on-yaws</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-05-06:2835</id>
    <published>2007-05-06T11:24:00Z</published>
    <updated>2007-05-06T11:28:17Z</updated>
    <category term="camping" />
    <category term="daemons" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/A2Cb_i-4QBI/daemonizing-ruby-scripts-for-monit" rel="alternate" type="text/html" />
    <title>Daemonizing Ruby Scripts for Monit</title>
<content type="html">
            &lt;p&gt;Monit is a very useful, if not occasionally frustrating tool for monitoring processes on a server. Many of you have probably used monit to keep your mongrel clusters up and running. Monit plays well with anything that has built in deamonization, but if you have a plain old Ruby script (to do file cleanups, synchronizations, or whatnot), you'll find that monit leaves you out to dry.&lt;/p&gt;

&lt;p&gt;Luckily, there's a nice gem called &lt;a href="http://daemons.rubyforge.org/"&gt;daemons&lt;/a&gt; that makes it dead simple to daemonize your Ruby scripts. Once you've daemonized a script, you can start, stop, and restart it by calling the script with one of those commands as the first argument. It takes care of writing out a PID file and redirecting STDOUT to a logfile.&lt;/p&gt;

&lt;p&gt;One very useful thing I needed to do was daemonize a Camping app, and since Camping doesn't have a -d option yet (hopefully someday it will), it's up to us to add that functionality. Let's see just how easy it is to write a control file for a Camping app. Here's a file named &lt;code&gt;campyctl.rb&lt;/code&gt;:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/local/lib/ruby&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubygems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;daemons&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Daemons&lt;/span&gt;.run(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/var/www/campy/campy.rb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;            {&lt;span class="sy"&gt;:mode&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:exec&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;             &lt;span class="sy"&gt;:dir&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/var/www/campy/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;             &lt;span class="sy"&gt;:dir_mode&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:normal&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;             &lt;span class="sy"&gt;:log_output&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;             &lt;span class="sy"&gt;:app_name&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;campy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;})&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now we can call &lt;code&gt;campyctl.rb start&lt;/code&gt; to fire up the camping app. Doing so will also give us a file called &lt;code&gt;campy.pid&lt;/code&gt; that will contain the PID of the Ruby process that's running Camping, and a &lt;code&gt;campy.log&lt;/code&gt; file with the redirected STDOUT. With a true daemon in place, we can easily set up monit to keep an eye on the process and issue a start command if it goes down!&lt;/p&gt;

&lt;p&gt;If you need daemon functionality, totally check out &lt;code&gt;daemons&lt;/code&gt;. In addition to the control file paradigm above it offers several other ways to daemonize your code. Great stuff, and a huge timesaver!&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/5/6/daemonizing-ruby-scripts-for-monit</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-05-01:2828</id>
    <published>2007-05-01T19:19:00Z</published>
    <updated>2007-05-01T19:27:36Z</updated>
    <category term="apache" />
    <category term="mephisto" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/2svZT1y9BVE/multi-site-mephisto-apache-2-2-config" rel="alternate" type="text/html" />
    <title>Multi-Site Mephisto Apache 2.2 Config</title>
<content type="html">
            &lt;p&gt;Mephisto truly is a wonderful piece of weblog/cms software. It's even more powerful in multi-site mode, where you can have completely separate blog instances running under a single installation. Doing this, however, requires a fair bit of RewriteRule magic in your Apache configuration. Crafting large sets of Apache rewrite rules is a very exacting science. One which I do not relish having to do more than once for a given set of behaviors. And so, to alleviate the pain for my future self and others, I present a full virtual host configuration suitable for use with Apache 2.2 and mod_proxy_balancer with a cluster of Mongrels.&lt;/p&gt;

&lt;p&gt;This config is for two sites: example.com and blog.example.com. Because of the way Mephisto stores cached pages, all requests to www.example.com are redirected to example.com (no www). This is wise &lt;a href="http://no-www.org/"&gt;in general&lt;/a&gt;. It proxies requests to a cluster of three mongrels.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;65&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  ServerName www.example.com&lt;tt&gt;
&lt;/tt&gt;  ServerAlias example.com&lt;tt&gt;
&lt;/tt&gt;  ServerAlias blog.example.com&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # admin's email&lt;tt&gt;
&lt;/tt&gt;  ServerAdmin awesome@example.com&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # paths&lt;tt&gt;
&lt;/tt&gt;  DocumentRoot /var/www/example/current/public&lt;tt&gt;
&lt;/tt&gt;  ErrorLog /var/www/example/current/log/error_log&lt;tt&gt;
&lt;/tt&gt;  CustomLog /var/www/example/current/log/access_log combined&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  ServerSignature On&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  RewriteEngine On&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # no-www&lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]&lt;tt&gt;
&lt;/tt&gt;  RewriteRule (.*) http://example.com$1 [L,R=301]&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  # Don't redirect /admin*. Send it directly to rails. &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_URI} ^/admin.* &lt;tt&gt;
&lt;/tt&gt;  RewriteRule ^/(.*)$ balancer://example_cluster%{REQUEST_URI} [P,QSA,L]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Basic content redirection&lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{DOCUMENT_ROOT}/cache/%{HTTP_HOST}/index.html -f&lt;tt&gt;
&lt;/tt&gt;  RewriteRule ^/?$ /cache/%{HTTP_HOST}/index.html [QSA,L]&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_URI} !.*/mephisto/.*&lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{DOCUMENT_ROOT}/cache/%{HTTP_HOST}/$1.html -f&lt;tt&gt;
&lt;/tt&gt;  RewriteRule ^/([^.]+)$ /cache/%{HTTP_HOST}/$1.html [QSA,L]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # asset redirection &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_FILENAME} /assets/.* &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_FILENAME} !-f &lt;tt&gt;
&lt;/tt&gt;  RewriteRule ^/(assets)(.*)$ /assets/%{HTTP_HOST}/$2 [QSA,L]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # other redirection (imgs, js, css, ...) &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_FILENAME} !-f &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_URI} !.*/mephisto/.* &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_URI} !.*html &lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{REQUEST_URI} !^/cache&lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{DOCUMENT_ROOT}/cache/%{HTTP_HOST}/$1 -f&lt;tt&gt;
&lt;/tt&gt;  RewriteRule ^/(.*)$ /cache/%{HTTP_HOST}/$1 [QSA,L]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Redirect all non-static requests to cluster&lt;tt&gt;
&lt;/tt&gt;  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f&lt;tt&gt;
&lt;/tt&gt;  RewriteRule ^/(.*)$ balancer://example_cluster%{REQUEST_URI} [P,QSA,L]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Rewrite debugging&lt;tt&gt;
&lt;/tt&gt;  # RewriteLogLevel 4&lt;tt&gt;
&lt;/tt&gt;  # RewriteLog &amp;quot;/var/www/example/current/log/rewrite.log&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  # Error pages&lt;tt&gt;
&lt;/tt&gt;  ErrorDocument 503 /503.html&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  # Proxy setup&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;Proxy balancer://example_cluster&amp;gt;&lt;tt&gt;
&lt;/tt&gt;    BalancerMember http://127.0.0.1:5000&lt;tt&gt;
&lt;/tt&gt;    BalancerMember http://127.0.0.1:5001&lt;tt&gt;
&lt;/tt&gt;    BalancerMember http://127.0.0.1:5002&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;/Proxy&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  ProxyPreserveHost On&lt;tt&gt;
&lt;/tt&gt;&amp;lt;/VirtualHost&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Based loosely on the config from the &lt;a href="http://mephisto.stikipad.com/help/revision/show/24/HostingMultipleSites"&gt;Mephisto Wiki&lt;/a&gt;.&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/5/1/multi-site-mephisto-apache-2-2-config</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-04-30:2822</id>
    <published>2007-04-30T04:48:00Z</published>
    <updated>2007-04-30T04:49:28Z</updated>
    <category term="erlang" />
    <category term="rebar" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/XIFf4gjxw3c/calling-erlang-from-ruby-teaser" rel="alternate" type="text/html" />
    <title>Calling Erlang from Ruby (Teaser)</title>
<content type="html">
            &lt;p&gt;With Moore's Law about to crumble from beneath our feet, we all need to start thinking about how to make use of those 64 core processors we'll be rockin' in our laptops in a few years. Ruby is an amazing language for many tasks, but sadly concurrent programming is not one of them. In preparation for the future I could consider dropping Ruby altogether and find another more appropriate language. But that would be madness. Ruby is awesome. What if I could still write the bulk of my projects in Ruby, but farm out the threaded stuff to the concurrency mercenary that is Erlang? That would be cool, right?&lt;/p&gt;

&lt;p&gt;Consider a small Erlang module:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;-module(funs).&lt;tt&gt;
&lt;/tt&gt;-export([add/2, cat/2, fac/1]).&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;add(A, B) -&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  A + B.&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;cat(A, B) -&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  A ++ B.&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;fac(N) -&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  fac(1, N).&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;fac(Memo, 0) -&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  Memo;&lt;tt&gt;
&lt;/tt&gt;fac(Memo, N) -&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  fac(Memo * N, N - 1).&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;I'd like to be able to call these Erlang functions from my Ruby code without a lot of fuss. Hmm, how's this for a low-fuss approach:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rebar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;funs = &lt;span class="co"&gt;Rebar&lt;/span&gt;::&lt;span class="co"&gt;Erlang&lt;/span&gt;.new(&lt;span class="sy"&gt;:funs&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="i"&gt;5500&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;funs.add(&lt;span class="i"&gt;1&lt;/span&gt;, &lt;span class="i"&gt;2&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# =&amp;gt; 3&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;funs.cat(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# =&amp;gt; &amp;quot;foobar&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;funs.fac(&lt;span class="i"&gt;10&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# =&amp;gt; 3628800&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Wow, that would be nice. Good thing I just spent the last two days writing some code to make it a reality!&lt;/p&gt;

&lt;p&gt;The library is called &lt;code&gt;Rebar&lt;/code&gt; (&lt;strong&gt;R&lt;/strong&gt;uby to &lt;strong&gt;E&lt;/strong&gt;rlang &lt;strong&gt;B&lt;/strong&gt;ridge &lt;strong&gt;A&lt;/strong&gt;nd &lt;strong&gt;R&lt;/strong&gt;unner). Rebar has two parts: an Erlang server and a Ruby client. The server listens for JSON-RPC requests, calls the specified Erlang function, and responds with a JSON-RPC response. The Ruby client object simply accepts any method name, captures it with &lt;code&gt;method_missing&lt;/code&gt;, wraps everything up in a JSON-RPC request, fires it off, waits for the response, and then extracts the result out of the JSON-RPC response, returning it like a normal Ruby call.&lt;/p&gt;

&lt;p&gt;It's still too hackish to release, but with some error handling and robustification, it'll be all good. If you'd like to help out with Rebar, you just let me know.&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/4/30/calling-erlang-from-ruby-teaser</feedburner:origLink></entry>
  <entry xml:base="http://rubyisawesome.com/">
    <author>
      <name>mojombo</name>
    </author>
    <id>tag:rubyisawesome.com,2007-04-23:2815</id>
    <published>2007-04-23T06:40:00Z</published>
    <updated>2007-04-23T06:41:36Z</updated>
    <category term="rubinius" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/ruby_is_awesome/~3/FeRsGx0-Rpw/rubinius-hacking-with-evan-phoenix" rel="alternate" type="text/html" />
    <title>Rubinius Hacking with Evan Phoenix</title>
<content type="html">
            &lt;p&gt;After the Silicon Valley Ruby Conference ended today, a few of us gathered up at my place to hack on &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt; while Evan was around. I think I've got enough of a feel for Rubinius now that I can make some meaningful contributions. I want to flesh out the Time class in preparation for my work on BigTime. A huge thanks to Evan and all the Rubinius guys for what looks to be an extremely promising project. I can't wait to get to know it better.&lt;/p&gt;

&lt;p&gt;Clockwise from the left: &lt;a href="http://blog.hasmanythrough.com/"&gt;Josh Susser&lt;/a&gt;, &lt;a href="http://brainspl.at/"&gt;Ezra Zygmuntowicz&lt;/a&gt;, &lt;a href="http://glu.ttono.us/"&gt;Kevin Clark&lt;/a&gt;, &lt;a href="http://www.kylemaxwell.com/"&gt;Kyle Maxwell&lt;/a&gt;, &lt;a href="http://errtheblog.com/"&gt;Chris Wanstrath&lt;/a&gt;, and &lt;a href="http://blog.fallingsnow.net/"&gt;Evan Phoenix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://rubyisawesome.com/assets/2007/4/23/postconf.jpg" alt="Hack Time" /&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://rubyisawesome.com/2007/4/23/rubinius-hacking-with-evan-phoenix</feedburner:origLink></entry>
</feed>
