Handle multiple fibers waiting for more resources than available

This commit is contained in:
Brian J. Cardiff 2019-09-02 14:14:46 -03:00
parent 5c1c1ab910
commit afad416417

View file

@ -63,19 +63,28 @@ module DB
def checkout : T def checkout : T
res = sync do res = sync do
resource = if @idle.empty? resource = nil
if can_increase_pool?
@inflight += 1 until resource
r = unsync { build_resource } resource = if @idle.empty?
@inflight -= 1 if can_increase_pool?
r @inflight += 1
r = unsync { build_resource }
@inflight -= 1
r
else
unsync { wait_for_available }
# The wait for available can unlock
# multiple fibers waiting for a resource.
# Although only one will pick it due to the lock
# in the end of the unsync, the pick_available
# will return nil
pick_available
end
else else
unsync { wait_for_available }
pick_available pick_available
end end
else end
pick_available
end
@idle.delete resource @idle.delete resource
@ -194,7 +203,7 @@ module DB
end end
private def pick_available private def pick_available
@idle.first @idle.first?
end end
private def wait_for_available private def wait_for_available