try Request Zones
Asks for a set of zones, and answers null when some zone of it is already promised.
requestZones with the one refusable condition turned into an answer. A zone carries one promise at a time, and by default a second asker is refused rather than put in a queue behind the first -- ZoneOverlap.QUEUE is the opt-in for waiting instead. So a model whose closures land where they land -- spills, most obviously -- has to say what an overlap means. This is how it says it, in one call that cannot be got wrong.
The hand-written alternative is the reason this exists. The test that matters is a promise, not a hold: asking for a zone another holder already holds is perfectly ordinary and simply waits for the hold to end. A guard written by hand tends to test the hold as well, and then refuses closures that would have worked.
// A spill landing where one is already being dealt with is part of that spill.
val request = space.tryRequestZones(crew, extent, action)
if (request == null) {
absorbed.increment()
return
}Everything else a request must satisfy still raises: an empty set, a repeated zone, a zone of another guide path, or a holder that already has a request are programming errors rather than conditions of the guide path, and answering null to those would hide a defect.
tryRequestZone is the single-zone spelling. It was left out at first, on the argument that what matters is handling the null rather than how the call is written -- true, but it left requestZone with no try counterpart while requestZones had one, and an asymmetry a reader has to remember is worth more than the argument against it.
Return
the request, or null when some zone of the set is already promised to another holder
Parameters
who is taking the space
the zones to take, all on this guide path, distinct, at least one
told when the hold begins and when it ends