From afad416417f31878f8378900aa2ad8a702cc8585 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Mon, 2 Sep 2019 14:14:46 -0300 Subject: [PATCH] Handle multiple fibers waiting for more resources than available --- src/db/pool.cr | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/db/pool.cr b/src/db/pool.cr index 7046cb0..5acffaa 100644 --- a/src/db/pool.cr +++ b/src/db/pool.cr @@ -63,19 +63,28 @@ module DB def checkout : T res = sync do - resource = if @idle.empty? - if can_increase_pool? - @inflight += 1 - r = unsync { build_resource } - @inflight -= 1 - r + resource = nil + + until resource + resource = if @idle.empty? + if can_increase_pool? + @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 - unsync { wait_for_available } pick_available end - else - pick_available - end + end @idle.delete resource @@ -194,7 +203,7 @@ module DB end private def pick_available - @idle.first + @idle.first? end private def wait_for_available