Problems
- deref on some IDerefs can block.
- futures
- promises
- problem - If you can't accept blocking indefinitely you have no alternative
- some reference type might not yet have a value
- futures
- promises
- delays
- 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
- e.g. IMightBlock
- offer a deref with timeout
- e.g. (deref blocking-ref timeout timeout-val)
- categorize references that might not yet have a value
- e.g. IMightNotHaveAValue
- offer a query fn for that
- (has-value? aref)
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
- but causes paranoia?
- 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
await-for
for Agent
- 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
- Future
Labels:
1 Comment
Hide/Show CommentsMay 09, 2011
Kevin Downey
watchers on promises might also be useful