Ah, the weirdness was because I forgot to make future-try wait for the
future it creates.

(defmacro future-try [& body]
  `(let [thread-atom# (atom nil)]
     (try
       (reset! thread-atom# (future (try ~@body)))
       *@@thread-atom#*
       (catch Exception e#
         (if-let [thread# @thread-atom#]
           (future-cancel thread#))
         (throw e#)))))

Using this does cancel the inner thread as soon as you cancel the outer
one, it does run the "catch" branch of code, and it does stop the loop. You
can even replace (while (not (Thread/interrupted)) ...) with (while true
...) and it still behaves this way. It might seem unexpected or undesirable
that it runs the "catch" branch, but it does seem like a good idea to let a
future-try/catch block clean up after itself. /shrug

-- Dan Burton

On Fri, Apr 29, 2016 at 6:26 PM, Dan Burton <danburton.em...@gmail.com>
wrote:

> Here's something to explore.
>
> (defmacro future-try [& body]
>   `@(future (try ~@body)))
>
> (defn test-f2 [initial-v]
>   (let [n (atom initial-v)]
>     [n
>      (future (while (not (Thread/interrupted))
>                (future-try
>                  (Thread/sleep 5000)
>                  (swap! n inc)
>                  (println @n)
>                  (catch Exception e (println "whoops")))))]))
>
> (def t2 (test-f2 11))
>
> test-f2 is the same as in your original email, except it uses future-try
> instead of try.
> It seems to allow you to correctly cancel the thread. It doesn't hit the
> "whoops" branch.
>
> But something is off. It doesn't stop the inner block, and the final
> number is printed *after* the outer future is cancelled. I would expect
> canceling a future to cancel all of its children, but apparently this is
> not the case.
>
> ----------
>
> Want to see some really weird stuff? Here's how I tried to make future-try
> attempt to cancel its children:
>
> (defmacro future-try [& body]
>   `(let [thread-atom# (atom nil)]
>      (try
>        (reset! thread-atom# (future (try ~@body)))
>        (catch Exception e#
>          (if-let [thread# @thread-atom#]
>            (future-cancel thread#))
>          (throw e#)))))
>
> Try running (def f2 (test-f2 11)) with that future-try, and it goes crazy.
> After waiting 5 seconds, it spews out numbers up to around 2031, then stops
> because (second f2) wasn't able to allocate any more threads. I have no
> explanation for this.
>
> -- Dan Burton
>
> On Fri, Apr 29, 2016 at 5:25 PM, Tom Bodenheimer <
> tom.bodenhei...@gmail.com> wrote:
>
>> Hi Ashish,
>>
>> It actually appears that there is no exception thrown by default when
>> future-cancel is called on the thread *unless* you manage to overlook java
>> functions that include some type of interrupt status handling.  As I
>> managed to do.
>>
>> Take a look at my below test-interrupt-status-2 that includes a try/catch
>> loop to see what I mean.
>>
>> Thanks.
>>
>>
>> On Friday, April 29, 2016 at 9:35:39 AM UTC-4, Ashish Negi wrote:
>>>
>>> To stop any thread.. interrupts are send to it.
>>> And threads handle this by throwing exception so that programmer can
>>> decide what to do
>>> depending upon the kind of exception it gets. (you may get different
>>> exceptions)
>>>
>>> Since you are catching the exception, your thread is never stopped.. and
>>> hence future-cancel returns false.
>>>
>>> If you throw again.. exception would unwind your while loop and stop the
>>> thread.
>>> hence.. future-cancel is able to stop the thread and returns true.
>>>
>>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@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+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to