class AccessStack

Constants

TimeoutError
VERSION

Attributes

count[R]
create[RW]
destroy[RW]
expires[RW]
size[RW]
timeout[RW]
validate[RW]

Public Class Methods

new(opts={}) click to toggle source
# File lib/access_stack.rb, line 11
def initialize(opts={})
        @timeout = opts[:timeout] || opts["timeout"] || 5
        @size = opts[:size] || opts["size"] || 5
        @expires = opts[:expires] || opts["expires"] || -1
        @expr_hash = {}
        @stack = []
        @count = 0
        @mutex = Mutex.new
        @create = opts[:create] || opts["create"]
        @destroy = opts[:destroy] || opts["destroy"]
        @validate = opts[:validate] || opts["validate"]
end

Public Instance Methods

create_objects(num=1) click to toggle source
# File lib/access_stack.rb, line 76
def create_objects(num=1)
        created_count = 0

        threadsafe do
                num.times do
                        if @count < @size
                                @stack.push create_obj
                                @count += 1
                                created_count += 1
                        end
                end
        end
        
        created_count
end
empty!() click to toggle source
# File lib/access_stack.rb, line 62
def empty!
        return if @count == 0
        threadsafe do
                @stack.each(&@destroy.method(:call))
                @expr_hash.clear
                @stack.clear
                @count = 0
        end
end
empty?() click to toggle source
# File lib/access_stack.rb, line 92
def empty?
        @count == 0
end
fill() click to toggle source
# File lib/access_stack.rb, line 72
def fill
        create_objects @count
end
reap!() click to toggle source
# File lib/access_stack.rb, line 50
def reap!
        return true if @count == 0
        threadsafe do
                @stack.reject(&method(:obj_valid)).each do |instance|
                        @destroy.call instance
                        @expr_hash.delete instance
                        @stack.delete instance
                        @count -= 1
                end
        end
end
with(&block) click to toggle source
# File lib/access_stack.rb, line 24
def with(&block)
        begin
                obj = nil
        
                threadsafe do
                        obj = @stack.pop
                end
        
                if !(obj_valid obj)
                        obj = nil
                        @count -= 1
                end
        
                if @count < @size && obj.nil?
                        @count += 1
                        obj = create_obj
                end

                return block.call obj
        ensure
                threadsafe do
                        @stack.push obj
                end
        end
end

Private Instance Methods

create_obj() click to toggle source
# File lib/access_stack.rb, line 113
def create_obj
        obj = @create.call
        @expr_hash[obj] = Time.now
        obj
end
obj_valid(obj) click to toggle source
# File lib/access_stack.rb, line 119
def obj_valid(obj)
        block_valid = @vaildate.call obj rescue true
        expired = (@expires > 0 && @expr_hash[obj].to_f-Time.now.to_f > @expires)
        !expired && block_valid
end
threadsafe(&block) click to toggle source
# File lib/access_stack.rb, line 98
def threadsafe(&block)
        begin
          Timeout::timeout @timeout do
            @mutex.lock
          end
        
                block.call
                @mutex.unlock
                true
        rescue Timeout::Error
                raise TimeoutError, "Failed to obtain a lock fast enough."
        end
        false
end