<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,8 @@
+=
+  * Major changes
+    * Remove dependency on Erlectricity
+    * Simplify processing loop
+
 = 1.0.0 / 2009-10-19
   * No Changes. Production ready!
 </diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -11,8 +11,7 @@ begin
     gem.authors = [&quot;Tom Preston-Werner&quot;]
     gem.files.include([&quot;ext&quot;])
     gem.extensions &lt;&lt; 'ext/extconf.rb'
-    gem.add_dependency('erlectricity', '&gt;= 1.1.0')
-    gem.add_dependency('bert', '&gt;= 1.0.0')
+    gem.add_dependency('bert', '&gt;= 1.1.0')
     gem.add_dependency('bertrpc', '&gt;= 1.0.0')
 
     # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -14,6 +14,10 @@ mod(:slowcalc) do
     sleep(rand * 2)
     a + b
   end
+
+  fun(:superslow) do
+    sleep 10
+  end
 end
 
 # Throw an error</diff>
      <filename>examples/calc.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,11 @@ class Ernie
   self.current_mod = nil
   self.logger = nil
 
+  # Record a module.
+  #   +name+ is the module Symbol
+  #   +block+ is the Block containing function definitions
+  #
+  # Returns nothing
   def self.mod(name, block)
     m = Mod.new(name)
     self.current_mod = m
@@ -18,69 +23,129 @@ class Ernie
     block.call
   end
 
+  # Record a function.
+  #   +name+ is the function Symbol
+  #   +block+ is the Block to associate
+  #
+  # Returns nothing
   def self.fun(name, block)
     self.current_mod.fun(name, block)
   end
 
+  # Set the logfile to given path.
+  #   +file+ is the String path to the logfile
+  #
+  # Returns nothing
   def self.logfile(file)
     self.logger = Logger.new(file)
   end
 
+  # If logging is enabled, log the given text.
+  #   +text+ is the String to log
+  #
+  # Returns nothing
   def self.log(text)
     self.logger.info(text) if self.logger
   end
 
+  # Dispatch the request to the proper mod:fun.
+  #   +mod+ is the module Symbol
+  #   +fun+ is the function Symbol
+  #   +args+ is the Array of arguments
+  #
+  # Returns the Ruby object response
   def self.dispatch(mod, fun, args)
-    xargs = BERT::Decoder.convert(args)
-    self.log(&quot;-- &quot; + [mod, fun, xargs].inspect)
     self.mods[mod] || raise(ServerError.new(&quot;No such module '#{mod}'&quot;))
     self.mods[mod].funs[fun] || raise(ServerError.new(&quot;No such function '#{mod}:#{fun}'&quot;))
-    res = self.mods[mod].funs[fun].call(*xargs)
-    BERT::Encoder.convert(res)
+    self.mods[mod].funs[fun].call(*args)
   end
 
+  # Read the length header from the wire.
+  #   +input+ is the IO from which to read
+  #
+  # Returns the size Integer if one was read
+  # Returns nil otherwise
+  def self.read_4(input)
+    raw = input.read(4)
+    return nil unless raw
+    raw.unpack('N').first
+  end
+
+  # Read a BERP from the wire and decode it to a Ruby object.
+  #   +input+ is the IO from which to read
+  #
+  # Returns a Ruby object if one could be read
+  # Returns nil otherwise
+  def self.read_berp(input)
+    packet_size = self.read_4(input)
+    return nil unless packet_size
+    bert = input.read(packet_size)
+    BERT.decode(bert)
+  end
+
+  # Write the given Ruby object to the wire as a BERP.
+  #   +output+ is the IO on which to write
+  #   +ruby+ is the Ruby object to encode
+  #
+  # Returns nothing
+  def self.write_berp(output, ruby)
+    data = BERT.encode(ruby)
+    output.write([data.length].pack(&quot;N&quot;))
+    output.write(data)
+  end
+
+  # Start the processing loop.
+  #
+  # Loops forever
   def self.start
     self.log(&quot;Starting&quot;)
     self.log(self.mods.inspect)
-    receive do |f|
-      f.when([:call, Symbol, Symbol, Array]) do |mod, fun, args|
-        self.log(&quot;-&gt; &quot; + [:call, mod, fun, args].inspect)
+
+    input = IO.new(3)
+    output = IO.new(4)
+    input.sync = true
+    output.sync = true
+
+    loop do
+      iruby = self.read_berp(input)
+      unless iruby
+        puts &quot;Could not read BERP length header. Ernie server may have gone away. Exiting now.&quot;
+        exit!
+      end
+
+      if iruby.size == 4 &amp;&amp; iruby[0] == :call
+        mod, fun, args = iruby[1..3]
+        self.log(&quot;-&gt; &quot; + iruby.inspect)
         begin
           res = self.dispatch(mod, fun, args)
-          xres = [:reply, res]
-          self.log(&quot;&lt;- &quot; + xres.inspect)
-          f.send!(xres)
+          oruby = t[:reply, res]
+          self.log(&quot;&lt;- &quot; + oruby.inspect)
+          write_berp(output, oruby)
         rescue ServerError =&gt; e
-          xres = [:error, [:server, 0, e.class.to_s, e.message, e.backtrace]]
-          self.log(&quot;&lt;- &quot; + xres.inspect)
+          oruby = t[:error, t[:server, 0, e.class.to_s, e.message, e.backtrace]]
+          self.log(&quot;&lt;- &quot; + oruby.inspect)
           self.log(e.backtrace.join(&quot;\n&quot;))
-          f.send!(xres)
+          write_berp(output, oruby)
         rescue Object =&gt; e
-          xres = [:error, [:user, 0, e.class.to_s, e.message, e.backtrace]]
-          self.log(&quot;&lt;- &quot; + xres.inspect)
+          oruby = t[:error, t[:user, 0, e.class.to_s, e.message, e.backtrace]]
+          self.log(&quot;&lt;- &quot; + oruby.inspect)
           self.log(e.backtrace.join(&quot;\n&quot;))
-          f.send!(xres)
+          write_berp(output, oruby)
         end
-        f.receive_loop
-      end
-
-      f.when([:cast, Symbol, Symbol, Array]) do |mod, fun, args|
+      elsif iruby.size == 4 &amp;&amp; iruby[0] == :cast
+        mod, fun, args = iruby[1..3]
         self.log(&quot;-&gt; &quot; + [:cast, mod, fun, args].inspect)
         begin
           self.dispatch(mod, fun, args)
         rescue Object =&gt; e
           # ignore
         end
-        f.send!([:noreply])
-        f.receive_loop
-      end
-
-      f.when(Any) do |any|
-        self.log(&quot;-&gt; &quot; + any.inspect)
-        xres = [:error, [:server, 0, &quot;Invalid request: #{any.inspect}&quot;]]
-        self.log(&quot;&lt;- &quot; + xres.inspect)
-        f.send!(xres)
-        f.receive_loop
+        write_berp(output, t[:noreply])
+      else
+        self.log(&quot;-&gt; &quot; + iruby.inspect)
+        oruby = t[:error, t[:server, 0, &quot;Invalid request: #{iruby.inspect}&quot;]]
+        self.log(&quot;&lt;- &quot; + oruby.inspect)
+        write_berp(output, oruby)
       end
     end
   end</diff>
      <filename>lib/ernie.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>bf7e17b1c26b1be768648575aa3339c72c7906f9</id>
    </parent>
  </parents>
  <author>
    <name>Tom Preston-Werner</name>
    <email>tom@mojombo.com</email>
  </author>
  <url>http://github.com/mojombo/ernie/commit/d581d0c4ddd97c07696b64b32cf5b355c50af42f</url>
  <id>d581d0c4ddd97c07696b64b32cf5b355c50af42f</id>
  <committed-date>2009-10-28T17:08:05-07:00</committed-date>
  <authored-date>2009-10-28T15:34:59-07:00</authored-date>
  <message>remove dependency on erlectricity</message>
  <tree>6ca7dff3f32af1bfcaac3e5c7b2f381af24adcb9</tree>
  <committer>
    <name>Tom Preston-Werner</name>
    <email>tom@mojombo.com</email>
  </committer>
</commit>
