Bug in printing futures

78 views
Skip to first unread message

Dave Ray

unread,
Oct 11, 2012, 10:46:57 AM10/11/12
to clo...@googlegroups.com
In Clojure 1.4, I came across the following this week:

  user=> (def f (future (Thread/sleep 20000)))
  #'user/f
  user=> f
  #<core$future_call$reify__6110@27adc5f7: :pending>
  user=> (future-cancel f)
  true
  user=> f
  CancellationException   java.util.concurrent.FutureTask$Sync.innerGet (FutureTask.java:220)

That is, when printing a future, the cancellation state isn't checked for resulting in an exception when Future.get() is called. It's more annoying when the future is part of a larger data structure.

Cheers,

Dave


AtKaaZ

unread,
Oct 11, 2012, 4:53:34 PM10/11/12
to clo...@googlegroups.com
I notice it happens on Clojure 1.5.0-master-SNAPSHOT also.
Calling something like:
(future-cancelled? f)
true
before getting @f makes sense, but since I'm a clojure newb I don't know what showing "f" (not @f) would show. Maybe it should show something like:
#<core$future_call$reify__3499@7c9391d9: :cancelled>
and only @f should throw. That would make some sense to me. And it would make me understand what you wanted.
But it appears as if it's trying to also show @f  or maybe only show @f instead of the ":cancelled" part, as it does when the future is "future-done?"






--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Stuart Sierra

unread,
Oct 12, 2012, 2:34:50 PM10/12/12
to clo...@googlegroups.com
Patch welcome.
-S

AtKaaZ

unread,
Oct 12, 2012, 9:56:49 PM10/12/12
to clo...@googlegroups.com
Hi S, that's encouraging, I've to admit I've been poking at this for a few hours now, but I'm not as productive as the (real)programmers.

I've yet to read the following which is a how to submit patches:
http://dev.clojure.org/display/design/JIRA+workflow

Meanwhile poking around, I've found the two locations that are showing :pending and I've learned quite some things in the process. core_print.clj and dispatch.clj are the relevant files for showing the future ( => f ) respectively for (clojure.pprint/pprint f)

I've also found a few relevant inconsistencies between clojure.pprint/pprint and the normal printing (how do you call that), it's clearly no big deal since it's just printing:
(let [d (delay (throw (Exception. "a")) 100)] (print d) (clojure.pprint/pprint d) d)
 #<Delay@8526fa: :pending>#<Delay@8526fa: :not-delivered>
 #<Delay@8526fa: :pending>
 (let [d (delay (throw (Exception. "a")) 100)] (print d) (clojure.pprint/pprint d) d)
 #<Delay@2caf64a6: :pending>#<Delay@2caf64a6: :not-delivered>
 #<Delay@2caf64a6: :pending>

Notice that some say :pending and one says :not-delivered

I've also considered this case(or similar to others like promise/delay/future):
=> (def d (delay (throw (Exception. "a")) 100))
#'cloj2.ka/d
=> d
#<Delay@235c710: :pending>
=> @d
Exception a  cloj2.ka/fn--7187 (NO_SOURCE_FILE:1)
=> d
#<Delay@235c710: :pending>

At this time, I've been thinking that instead of :pending maybe there could be something else like :threw especially considering that it can never recover if it threw (right?), so having :pending might suggest that it is still working, maybe even pending is not quite right for delay. Maybe I'm getting too wannabe perfectionist here, after-all it's not one of my projects to do such detailed analysis :) - if it were, I'd be putting quite a few different messages here like: Delay :executing, Delay :threw, Delay :completed (and the return value)

I feel like I'm overthinking this, the only real issue is really that of printing an interrupted future should not throw.

At this time I'm not yet sure if I should pursue making a patch mainly because I feel it would be incomplete to just fix the printing future issue and not the other tiny things that I mentioned(but that's more of a fault in me for wanting all addressed) and also because it seems somewhat complicated to do, ie. required CA as I see here: http://clojure.org/patches

Thanks.

PS: someone who knows can probably do the futures patch in under 10 minutes, it would take me some hours I admit :)
Whoever does it, don't forget to add test cases in test_pretty.clj  currently somewhere at line 231:
(tst-pprint 20 future-unfilled) #"#<Future@[0-9a-f]+: \r?\n  :pending>"

On Fri, Oct 12, 2012 at 8:34 PM, Stuart Sierra <the.stua...@gmail.com> wrote:
Patch welcome.
-S
Reply all
Reply to author
Forward
0 new messages