clojure (with-timeout … macro)

前端 未结 3 729
-上瘾入骨i
-上瘾入骨i 2021-02-09 01:50

I\'m looking for a macro that will throw an exception if an expression takes longer than X seconds to complete.

3条回答
  •  广开言路
    2021-02-09 02:39

    This question has better answers here: Executing a function with a timeout

    Futures to the rescue!

    user=> (let [f (future (reduce * (range 1 1001)))]
      (.get f 1 java.util.concurrent.TimeUnit/MILLISECONDS))
    java.util.concurrent.TimeoutException (NO_SOURCE_FILE:0)
    

    And to make a macro of it:

    (defmacro time-limited [ms & body]
      `(let [f# (future ~@body)]
         (.get f# ~ms java.util.concurrent.TimeUnit/MILLISECONDS)))
    

    So you can do this:

    user=> (time-limited 1 (reduce * (range 1 1001)))
    java.util.concurrent.TimeoutException (NO_SOURCE_FILE:0)
    user=> (time-limited 1 (reduce * (range 1 101)))
    93326215443944152681699238856266700490715968264381621468592963895217599993229915
    608941463976156518286253697920827223758251185210916864000000000000000000000000
    

提交回复
热议问题