Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing a function with a timeout

Tags:

clojure

What would be an idiomatic way of executing a function within a time limit? Something like,

(with-timeout 5000
 (do-somthing))

Unless do-something returns within 5000 throw an exception or return nil.

EDIT: before someone points it out there is,

clojure (with-timeout ... macro)

but with that the future keeps executing that does not work in my case.

like image 273
Hamza Yerlikaya Avatar asked Jul 14 '11 14:07

Hamza Yerlikaya


People also ask

What is a timeout function?

The setTimeout() method executes a block of code after the specified time. The method executes the code only once. The commonly used syntax of JavaScript setTimeout is: setTimeout(function, milliseconds);

How do you call a timeout function in Python?

Then it's as simple as this to timeout a test or any function you like: @timeout(5.0) # if execution takes longer than 5 seconds, raise a TimeoutError def test_base_regression(self): ... Be careful since this does not terminate the function after timeout is reached!


2 Answers

I think you can do this reasonably reliably by using the timeout capability within futures:

  (defmacro with-timeout [millis & body]
    `(let [future# (future ~@body)]
      (try
        (.get future# ~millis java.util.concurrent.TimeUnit/MILLISECONDS)
        (catch java.util.concurrent.TimeoutException x# 
          (do
            (future-cancel future#)
            nil)))))

A bit of experimenting verified that you need to do a future-cancel to stop the future thread from continuing to execute....

like image 180
mikera Avatar answered Sep 19 '22 13:09

mikera


What about?

    (defn timeout [timeout-ms callback]
     (let [fut (future (callback))
           ret (deref fut timeout-ms ::timed-out)]
       (when (= ret ::timed-out)
         (future-cancel fut))
       ret))

    (timeout 100 #(Thread/sleep 1000))

    ;=> :user/timed-out
like image 27
Jeroen van Dijk Avatar answered Sep 18 '22 13:09

Jeroen van Dijk