Problems
- deref on some IDerefs can block.
- problem - If you can't accept blocking indefinitely you have no alternative
- some reference type might not yet have a value
- problem - if you need to make a decision based upon whether or not such a reference has a value you can't, without forcing/blocking
Possible solutions
- categorize references that can block
- offer a deref with timeout
- e.g. (deref blocking-ref timeout timeout-val)
- categorize references that might not yet have a value
- offer a query fn for that
Issues
- which (if any) of these make sense for other refs?
- timeout seems really confusing for non-blocking
- has-value? could be trivially true for other refs
- overload deref for timeout, or new fn name?
Wants
- I want to know if a potentially blocking deref has a value
future-done? for Future(.hasValue foo) for Promise
- I want to know if something has finished
await for Agentfuture-done? for FutureThread.isAlive (rare)
- I want to wait for something to finish
await for Agentderef for Future, Delay, and Promise
- I want to wait a specific amount of time for something to finish
- I want to prevent something from happening
future-cancel for FutureThreadPoolExecutor.remove for a custom thread pool- Avoid
deref on a Delay
Example Problem
- printing at the REPL looks through a deref
- this can block (possibly forever) if a data structure contains e.g. a promise
- The REPL should not perform the deref for a print request unless there is a value
- option 1: never deref possible blockers
- option 2: have a bindable val that controls how REPL prints blocking derefs, analogous to the controls for lazy data structures
- in any case, there needs to be a way to discover which derefs have a value
Facts
deref can block - Never for Var, Ref, Agent, and Atom
- Sometimes for Future, Delay, and Promise
- Java APIs
- Future
.get() blocks until complete - interruptible, throws InterruptedException
.get(long, TimeUnit) blocks for specified duration - throws TimeouotException if it times out
- interruptible, throws InterruptedException
.isDone() asks if finished.cancel(bool mayInterrupt) attempts to cancel - if already finished or cancelled, returns false
- if already running, tries to interrupt if argument is true
.isCancellled() asks if cancelled
- CountDownLatch
.await() blocks until latch reaches zero - interruptible, throws InterruptedException
.await(long, TimeUnit) blocks until latch reaches zero - returns false if it times out
- interruptible, throws InterruptedException
.getCount() returns current count
- Semaphore
- CyclicBarrier