<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>README.markdown</filename>
    </added>
    <added>
      <filename>lib/examples/simple_pop.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Copyright (c) 2008 Amos Elliston
+Copyright (c) 2009 Amos Elliston
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the</diff>
      <filename>LICENSE</filename>
    </modified>
    <modified>
      <diff>@@ -37,4 +37,4 @@ Rcov::RcovTask.new do |t|
   t.verbose = true
 end
 
-task :default =&gt; :rcov
+task :default =&gt; :test</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,12 +1,13 @@
 module AMQP
   class Exchange
+    attr_accessor :server, :type, :name, :opts, :key
 
     def initialize(server, type, name, opts = {})
       @server, @type, @name, @opts = server, type, name, opts
       @key = opts[:key]
 
       unless name == &quot;amq.#{type}&quot; or name == ''
-        @server.send_frame(
+        server.send_frame(
           Protocol::Exchange::Declare.new(
             { :exchange =&gt; name, :type =&gt; type, :nowait =&gt; true }.merge(opts)
           )
@@ -19,7 +20,7 @@ module AMQP
       out = []
 
       out &lt;&lt; Protocol::Basic::Publish.new(
-        { :exchange =&gt; name, :routing_key =&gt; opts.delete(:key) || @key }.merge(opts)
+        { :exchange =&gt; name, :routing_key =&gt; opts.delete(:key) || key }.merge(opts)
       )
       data = data.to_s
       out &lt;&lt; Protocol::Header.new(
@@ -32,16 +33,15 @@ module AMQP
       )
       out &lt;&lt; Frame::Body.new(data)
 
-      @server.send_frame(*out)
+      server.send_frame(*out)
     end
 
     def delete(opts = {})
-      @server.send_frame(Protocol::Exchange::Delete.new({ :exchange =&gt; name, :nowait =&gt; true }.merge(opts)))
+      server.send_frame(Protocol::Exchange::Delete.new({ :exchange =&gt; name, :nowait =&gt; true }.merge(opts)))
     end
 
     def reset
-      @deferred_status = nil
-      initialize(@server, @type, @name, @opts)
+      initialize(server, type, name, opts)
     end
   end
 end</diff>
      <filename>lib/amqp/exchange.rb</filename>
    </modified>
    <modified>
      <diff>@@ -71,6 +71,7 @@ module AMQP
 end
 
 if $0 =~ /bacon/ or $0 == __FILE__
+  require 'rubygems'
   require 'bacon'
   include AMQP
 </diff>
      <filename>lib/amqp/frame.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ module AMQP
       @server = server
       @opts   = opts
       @name   = name
-      @server.send_frame(
+      server.send_frame(
         Protocol::Queue::Declare.new({ :queue =&gt; name, :nowait =&gt; true }.merge(opts))
       )
     end
@@ -16,6 +16,7 @@ module AMQP
       server.send_frame(
         Protocol::Queue::Delete.new({ :queue =&gt; name, :nowait =&gt; true }.merge(opts))
       )
+      pp server.next_method
     end
 
     def pop(opts = {})
@@ -23,17 +24,15 @@ module AMQP
       server.send_frame(
         Protocol::Basic::Get.new({ :queue =&gt; name, :consumer_tag =&gt; name, :no_ack =&gt; !opts.delete(:ack), :nowait =&gt; true }.merge(opts))
       )
-      frame   = server.next_frame
-      return if frame.is_a?(Frame::Method) and frame.payload.is_a?(Protocol::Basic::GetEmpty)
+      method = server.next_method
+      return if method.is_a?(Protocol::Basic::GetEmpty)
 
-      method  = frame.payload
       self.delivery_tag = method.delivery_tag
 
-      frame   = server.next_frame
-      header  = frame.payload
-      frame   = server.next_frame
-      msg     = frame.payload
+      header = server.next_payload
+      msg    = server.next_payload
       raise 'unexpected length' if msg.length &lt; header.size
+
       msg
     end
 
@@ -59,8 +58,7 @@ module AMQP
       server.send_frame(
         Protocol::Queue::Declare.new({ :queue =&gt; name, :passive =&gt; true }.merge(opts))
       )
-      frame  = @server.next_frame
-      method = frame.payload 
+      method = server.next_method
       [method.message_count, method.consumer_count]
     end
 </diff>
      <filename>lib/amqp/queue.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,11 +11,11 @@ module AMQP
     attr_reader   :host, :port, :status
     attr_accessor :retry_at, :channel, :ticket
 
-    class Error           &lt; StandardError; end
-    class ConnectionError &lt; Error; end
-    class ServerError     &lt; Error; end
-    class ClientError     &lt; Error; end
-    class ServerDown      &lt; Error; end
+    class ConnectionError &lt; StandardError; end
+    class ServerError     &lt; StandardError; end
+    class ClientError     &lt; StandardError; end
+    class ServerDown      &lt; StandardError; end
+    class ProtocolError   &lt; StandardError; end
 
     def initialize(opts = {})
       @host   = opts[:host]  || 'localhost'
@@ -24,22 +24,48 @@ module AMQP
       @pass   = opts[:pass]  || 'guest'
       @vhost  = opts[:vhost] || '/'
       @insist = opts[:insist]
-      @channel= 0
       @status = 'NOT CONNECTED'
 
       @multithread = opts[:multithread]      
+      start_session
+    end
 
+    def start_session
+      @channel = 0
       write(HEADER)
       write([1, 1, VERSION_MAJOR, VERSION_MINOR].pack('C4'))
-      receive_frame
-    end
+      raise ProtocolError, 'bad start connection' unless next_method.is_a?(Protocol::Connection::Start)
 
-    def multithread?
-      @multithread
-    end
+      send_frame(
+        Protocol::Connection::StartOk.new(
+          {:platform =&gt; 'Ruby', :product =&gt; 'Carrot', :information =&gt; 'http://github.com/famosagle/carrot', :version =&gt; VERSION},
+          'AMQPLAIN',
+          {:LOGIN =&gt; @user, :PASSWORD =&gt; @pass},
+          'en_US'
+        )
+      )
 
-    def retry?
-      @retry_at.nil? or @retry_at &lt; Time.now
+      if next_method.is_a?(Protocol::Connection::Tune)
+        send_frame(
+          Protocol::Connection::TuneOk.new( :channel_max =&gt; 0, :frame_max =&gt; 131072, :heartbeat =&gt; 0)
+        )
+      end
+
+      send_frame(
+        Protocol::Connection::Open.new(:virtual_host =&gt; @vhost, :capabilities =&gt; '', :insist =&gt; @insist)
+      )
+      raise ProtocolError, 'bad open connection' unless next_method.is_a?(Protocol::Connection::OpenOk)
+
+      @channel = 1
+      send_frame(Protocol::Channel::Open.new)
+      raise ProtocolError, &quot;cannot open channel #{channel}&quot; unless next_method.is_a?(Protocol::Channel::OpenOk)
+
+      send_frame(
+        Protocol::Access::Request.new(:realm =&gt; '/data', :read =&gt; true, :write =&gt; true, :active =&gt; true, :passive =&gt; true)
+      )
+      method = next_method
+      raise ProtocolError, 'access denied' unless method.is_a?(Protocol::Access::RequestOk)
+      self.ticket = method.ticket
     end
 
     def send_frame(*args)
@@ -53,19 +79,50 @@ module AMQP
       end
     end
 
+    def next_frame
+      frame = Frame.get(self)
+      log :received, frame
+      frame
+    end
+
+    def next_method
+      next_payload
+    end
+
+    def next_payload
+      next_frame.payload
+    end
+
+    def close
+      send_frame(
+        Protocol::Channel::Close.new(:reply_code =&gt; 200, :reply_text =&gt; 'bye', :method_id =&gt; 0, :class_id =&gt; 0)
+      )
+      puts &quot;Error closing channel #{channel}&quot; unless next_method.is_a?(Protocol::Channel::CloseOk)
+
+      self.channel = 0
+      send_frame(
+        Protocol::Connection::Close.new(:reply_code =&gt; 200, :reply_text =&gt; 'Goodbye', :class_id =&gt; 0, :method_id =&gt; 0)
+      )
+      puts &quot;Error closing connection&quot; unless next_method.is_a?(Protocol::Connection::CloseOk)
+
+      close_socket
+    end
+
     def read(*args)
-      with_socket do |socket|
+      with_socket_management do |socket|
         socket.read(*args)
       end
     end
 
     def write(*args)
-      with_socket do |socket|
+      with_socket_management do |socket|
         socket.write(*args)
       end
     end
 
-    def with_socket(&amp;block)
+  private
+
+    def with_socket_management(&amp;block)
       retried = false
       begin
         mutex.lock if multithread?
@@ -75,6 +132,7 @@ module AMQP
         if not retried
           # Close the socket and retry once.
           close_socket
+          #start_session
           retried = true
           retry
         else
@@ -91,92 +149,6 @@ module AMQP
       end
     end
 
-    def next_frame
-      frame = Frame.get(self)
-      log :received, frame
-      frame
-    end
-
-    def receive_frame
-      frame = next_frame
-      return unless frame
-
-      case frame
-      when Frame::Header
-        @header = frame.payload
-        @body = ''
-        receive_frame
-
-      when Frame::Body
-        @body &lt;&lt; frame.payload
-        if @body.length &gt;= @header.size
-          @header.properties.update(@method.arguments)
-          @body = @header = @consumer = @method = nil
-        end
-
-      when Frame::Method
-        case method = frame.payload
-        when Protocol::Connection::Start
-          send_frame(
-            Protocol::Connection::StartOk.new(
-              {:platform =&gt; 'Ruby', :product =&gt; 'Carrot', :information =&gt; 'http://github.com/famosagle/carrot', :version =&gt; VERSION},
-              'AMQPLAIN',
-              {:LOGIN =&gt; @user, :PASSWORD =&gt; @pass},
-              'en_US'
-            )
-          )
-          receive_frame
-
-        when Protocol::Connection::Tune
-          send_frame(
-            Protocol::Connection::TuneOk.new( :channel_max =&gt; 0, :frame_max =&gt; 131072, :heartbeat =&gt; 0)
-          )
-          send_frame(
-            Protocol::Connection::Open.new(:virtual_host =&gt; @vhost, :capabilities =&gt; '', :insist =&gt; @insist)
-          )
-          receive_frame
-
-        when Protocol::Connection::Close
-          STDERR.puts &quot;#{method.reply_text} in #{Protocol.classes[method.class_id].methods[method.method_id]}&quot;
-
-        when Protocol::Connection::OpenOk
-          self.channel = 1
-          send_frame(Protocol::Channel::Open.new)
-          receive_frame
-
-        when Protocol::Channel::OpenOk
-          send_frame(
-            Protocol::Access::Request.new(:realm =&gt; '/data', :read =&gt; true, :write =&gt; true, :active =&gt; true, :passive =&gt; true)
-          )
-          receive_frame
-
-        when Protocol::Access::RequestOk
-          self.ticket = method.ticket
-
-        when Protocol::Basic::CancelOk, Protocol::Queue::DeclareOk
-
-        when Protocol::Channel::Close
-          raise Error, &quot;#{method.reply_text} in #{Protocol.classes[method.class_id].methods[method.method_id]} on #{@channel}&quot;
-
-        end
-      end
-    end
-
-    def close
-      send_frame(
-        Protocol::Channel::Close.new(:reply_code =&gt; 200, :reply_text =&gt; 'bye', :method_id =&gt; 0, :class_id =&gt; 0)
-      )
-      next_frame
-      self.channel = 0
-      send_frame(
-        Protocol::Connection::Close.new(:reply_code =&gt; 200, :reply_text =&gt; 'Goodbye', :class_id =&gt; 0, :method_id =&gt; 0)
-      )
-      next_frame
-      close_socket
-    end
-
-  private
-
     def socket
       return @socket if @socket and not @socket.closed?
       raise ServerDown, &quot;will retry at #{retry_at}&quot; unless retry?
@@ -203,6 +175,14 @@ module AMQP
       @socket
     end
 
+    def multithread?
+      @multithread
+    end
+
+    def retry?
+      @retry_at.nil? or @retry_at &lt; Time.now
+    end
+
     def unexpected_eof!
       raise ConnectionError, 'unexpected end of file' 
     end</diff>
      <filename>lib/amqp/server.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,6 +18,18 @@ class Carrot
   end
   class Error &lt; StandardError; end
 
+  def self.queue(name, opts = {})
+    instance(opts).queue(name, opts)
+  end
+
+  def self.stop
+    instance.stop
+  end
+
+  def self.instance(opts = {})
+    @instance ||= new(opts)
+  end
+
   def initialize(opts = {})
     @server = AMQP::Server.new(opts)
   end</diff>
      <filename>lib/carrot.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>README</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>add3c567bfa31e0afb502f470632150d07da463c</id>
    </parent>
  </parents>
  <author>
    <name>Amos Elliston</name>
    <email>amos@geni.com</email>
  </author>
  <url>http://github.com/famoseagle/carrot/commit/07ef0284b1de72fc052db2127cc122cc161f7550</url>
  <id>07ef0284b1de72fc052db2127cc122cc161f7550</id>
  <committed-date>2009-04-08T16:01:05-07:00</committed-date>
  <authored-date>2009-04-08T16:01:05-07:00</authored-date>
  <message>adding examples and readme</message>
  <tree>82a867fc6fbd173835c3d141ccae20fc5ac3ae9b</tree>
  <committer>
    <name>Amos Elliston</name>
    <email>amos@geni.com</email>
  </committer>
</commit>
