From: "byroot (Jean Boussier) via ruby-core" Date: 2025-12-02T15:57:37+00:00 Subject: [ruby-core:123978] [Ruby Feature#21721] Allow `Queue` and `SizedQueue` to be used as LIFO queues Issue #21721 has been updated by byroot (Jean Boussier). > isn't that complicated It isn't trivial either, but more importantly, it's not very performant. It used not to be important because checkout and checkin would only happen once per request. But async users demanded that we'd go through checkout and checking for very query, and now I have a new hotspot that I can't find ways to optimize. > Also I think one can't even do BiasableQueue (at least not that way) if that LIFO Queue was in core. I think it's doable, but regardless, I wouldn't mind getting rid of that either, it's not that useful, it's used in rare cases to drain the pool, we could find another solution. ---------------------------------------- Feature #21721: Allow `Queue` and `SizedQueue` to be used as LIFO queues https://bugs.ruby-lang.org/issues/21721#change-115408 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- ### Context Since `Queue` and `SizedQueue` gained a proper timeout mechanism, I've been wanting to use them to implement simpler and more efficient connection pools. However for connection pools you ideally want a LIFO queue because it's preferable to checkout the most recently used connection. ### Problem Both `Queue` and `SizedQueue` only support FIFO because you can only enqueue elements at the beginning of the backing array, and only dequeue at the end. `Queue#push` (aliased as `Queue#<<` and `Queue#enq`) calls `Array#unshift` on the backing array and `Queue#pop` (aliased as `Queue#deq` and `Queue#shift`) calls `Array#pop`. Hence it is impossible to use these two classes for anything other than FIFO queues. I tried to use `git blame` to see if there was a justification for this, but I ended up in a git blame loop around May 2000 https://github.com/ruby/ruby/commit/9da4f78db46764be6dae5e7e83ff48cbecb3fb23 ### Feature I'd like to introduce either of two new methods (or both) to allow for LIFO: - A method to dequeue from the beginning of the backing array (`array_shift`). - A method to enqueue from the end of the backing array (`array_push`). A difficulty I have however is that since the common `shift/pop/push` terms are already used with uncommon meaning, it's hard to come up with good names. Ideas welcome. ### Possible alternatives - Define different classes for LIFO queues - But I find that less flexible, and it means exposing new constant names in the global namespace. - Add an initializer argument to define the queue ordering, e.g. `Queue.new([], lifo: true)` - Similarly, I find this less flexible than to decide the order during enqueue/dequeue - Add an argument to `Queue#pop` and `Queue#push`, e.g. `queue.push(element, front: true)`. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/