Libby: pause a hold without losing your place
Libby lets readers use a library card to borrow library ebooks and audiobooks. Place a hold when a popular title is unavailable; if you are too busy to read, pause delivery and resume when ready.
Break down the problem and try your own design and implementation first. Then explore the reasoning to check states, edge cases, trade-offs, and ways to test your approach. The guide offers a reasoning path, not a complete implementation.
01
CODE EXERCISE
Build a queue that preserves paused positions
Implement an in-memory waiting queue for a library hold app. Readers can pause delivery temporarily, but after resuming they must participate in the next allocation in their original order.
- Initial data: Receive
[{id:"A",paused:true},{id:"B",paused:false},{id:"C",paused:false}]in joining order. id is a unique hold identifier; paused indicates a pause. After creation, the module owns its queue and does not modify the supplied array directly. - Operations and rules: Provide
setPaused(id, paused)to update a hold still in the queue and return the resulting Boolean. The identifier is guaranteed to exist. This operation must not change the order. ProvidetakeNext()to remove and return the first unpaused hold identifier. If none can be allocated, returnnulland leave the queue unchanged. Providesnapshot()to return ordered copies of{id,paused}records; changing a returned copy must not change the internal queue. You may choose different operation names. - Acceptance examples: For the initial queue, takeNext returns B. Resume A, then successive takeNext calls return A, C and null. In a separate queue containing only paused A, takeNext returns null and a snapshot still contains A. At this point, change A.paused to false in the returned snapshot; a new snapshot must still be [{id:"A",paused:true}]. Then resume A through setPaused, and takeNext returns A.
- Deliverable: Implement the module in a familiar language, run both sequences, and briefly explain how it preserves order and pause state together. No real account, page, network or expiry timer is needed.
Explore the reasoning
- Decide how to preserve stable queue order, then represent “skip for now” as information on the hold itself. Consider which example would break if paused readers moved to the back.
- Define the separate responsibilities of changing pause state and taking the next item. Remove a record only after a successful allocation.
- Trace both sequences, paying particular attention to preserving records when everyone is paused and preventing a returned snapshot from exposing mutable internal data.