class Async::LimitedQueue

@public Since ‘stable-v1`.
A queue which limits the number of items that can be enqueued.

def <<(item)

@parameter item [Object] The item to add to the queue.

If the queue is full, this method will block until there is space available.

Add an item to the queue.
def <<(item)
	while limited?
		@full.wait
	end
	
	super
end

def dequeue

@returns [Object] The next item in the queue.

If the queue is empty, this method will block until an item is available.

Remove and return the next item from the queue.
def dequeue
	item = super
	
	@full.signal
	
	return item
end

def enqueue(*items)

@parameter items [Array] The items to add to the queue.

If the queue is full, this method will block until there is space available.

Add multiple items to the queue.
def enqueue(*items)
	while !items.empty?
		while limited?
			@full.wait
		end
		
		available = @limit - @items.size
		@items.concat(items.shift(available))
		
		@available.signal unless self.empty?
	end
end

def initialize(limit = 1, full: Notification.new, **options)

@parameter full [Notification] The notification to use for signaling when the queue is full.
@parameter limit [Integer] The maximum number of items that can be enqueued.

Create a new limited queue.
def initialize(limit = 1, full: Notification.new, **options)
	super(**options)
	
	@limit = limit
	@full = full
end

def limited?

@returns [Boolean] Whether trying to enqueue an item would block.
def limited?
	@items.size >= @limit
end