diff --git a/warden/lib/warden/container/base.rb b/warden/lib/warden/container/base.rb index 823e0c9..3f8afc4 100644 --- a/warden/lib/warden/container/base.rb +++ b/warden/lib/warden/container/base.rb @@ -66,11 +66,7 @@ module Warden # Release resources required for every container instance. def release(resources) if network = resources.delete(:network) - # Release network after some time to make sure the kernel has - # time to clean up things such as lingering connections. - ::EM.add_timer(5) { - network_pool.release(network) - } + network_pool.release(network) end end diff --git a/warden/lib/warden/network.rb b/warden/lib/warden/network.rb index 7e86d27..a0ab350 100644 --- a/warden/lib/warden/network.rb +++ b/warden/lib/warden/network.rb @@ -9,11 +9,11 @@ module Warden include Comparable def <=>(other) - v <=> other.v + v <=> Octets.new(other).v end def eql?(other) - v == other.v + v == Octets.new(other).v end def hash diff --git a/warden/lib/warden/pool/network_pool.rb b/warden/lib/warden/pool/network_pool.rb index 1508624..421decd 100644 --- a/warden/lib/warden/pool/network_pool.rb +++ b/warden/lib/warden/pool/network_pool.rb @@ -8,19 +8,33 @@ module Warden attr_reader :netmask - def initialize(start_address, count) + # The release delay can be used to postpone address being acquired again + # after being released. This can be used to make sure the kernel has time + # to clean up things such as lingering connections. + + def initialize(start_address, count, options = {}) + @start_address = Warden::Network::Address.new(start_address) @netmask = Network::Netmask.new(255, 255, 255, 252) @pool = count.times.map { |i| - start_address + @netmask.size * i + [Time.mktime(1970), @start_address + @netmask.size * i] } + + @release_delay = options[:release_delay] || 5 end def acquire - @pool.shift + time, address = @pool.first + + if time && time < Time.now + @pool.shift + return address + end + + return nil end def release(address) - @pool.push address + @pool.push [Time.now + @release_delay, address] end end end diff --git a/warden/spec/pool/network_pool_spec.rb b/warden/spec/pool/network_pool_spec.rb new file mode 100644 index 0000000..bf55e1d --- /dev/null +++ b/warden/spec/pool/network_pool_spec.rb @@ -0,0 +1,32 @@ +require "spec_helper" + +describe Warden::Pool::NetworkPool do + + before(:each) do + @options = { :release_delay => 0.01 } + @network_pool = Warden::Pool::NetworkPool.new("127.0.0.0", 2, @options) + end + + it "holds as many addresses as specified" do + @network_pool.acquire.should == "127.0.0.0" + @network_pool.acquire.should == "127.0.0.4" + @network_pool.acquire.should be_nil + end + + it "delays releasing addresses" do + a1 = @network_pool.acquire + a2 = @network_pool.acquire + + # Release a1 + @network_pool.release(a1) + + # Verify it cannot be acquired + @network_pool.acquire.should be_nil + + # Sleep until the release delay has passed + sleep @options[:release_delay] + + # Verify it can be acquired + @network_pool.acquire.should == a1 + end +end