69 lines
2.6 KiB
Clojure
69 lines
2.6 KiB
Clojure
(ns babashka.wait
|
|
(:require [clojure.java.io :as io])
|
|
(:import [java.net Socket SocketException]))
|
|
|
|
(set! *warn-on-reflection* true)
|
|
|
|
(defn wait-for-port
|
|
"Waits for TCP connection to be available on host and port. Options map
|
|
supports `:timeout` and `:pause`. If `:timeout` is provided and reached,
|
|
`:default`'s value (if any) is returned. The `:pause` option determines
|
|
the time waited between retries."
|
|
([host port]
|
|
(wait-for-port host port nil))
|
|
([^String host ^long port {:keys [:default :timeout :pause] :as opts}]
|
|
(let [opts (merge {:host host
|
|
:port port}
|
|
opts)
|
|
t0 (System/currentTimeMillis)]
|
|
(loop []
|
|
(let [v (try (.close (Socket. host port))
|
|
(- (System/currentTimeMillis) t0)
|
|
(catch SocketException _e
|
|
(let [took (- (System/currentTimeMillis) t0)]
|
|
(if (and timeout (>= took timeout))
|
|
:wait-for-port.impl/timed-out
|
|
:wait-for-port.impl/try-again))))]
|
|
(cond (identical? :wait-for-port.impl/try-again v)
|
|
(do (Thread/sleep (or pause 100))
|
|
(recur))
|
|
(identical? :wait-for-port.impl/timed-out v)
|
|
default
|
|
:else
|
|
(assoc opts :took v)))))))
|
|
|
|
(defn wait-for-path
|
|
"Waits for file path to be available. Options map supports `:default`,
|
|
`:timeout` and `:pause`. If `:timeout` is provided and reached, `:default`'s
|
|
value (if any) is returned. The `:pause` option determines the time waited
|
|
between retries."
|
|
([path]
|
|
(wait-for-path path nil))
|
|
([^String path {:keys [:default :timeout :pause] :as opts}]
|
|
(let [opts (merge {:path path}
|
|
opts)
|
|
t0 (System/currentTimeMillis)]
|
|
(loop []
|
|
(let [v (when (not (.exists (io/file path)))
|
|
(let [took (- (System/currentTimeMillis) t0)]
|
|
(if (and timeout (>= took timeout))
|
|
:wait-for-path.impl/timed-out
|
|
:wait-for-path.impl/try-again)))]
|
|
(cond (identical? :wait-for-path.impl/try-again v)
|
|
(do (Thread/sleep (or pause 100))
|
|
(recur))
|
|
(identical? :wait-for-path.impl/timed-out v)
|
|
default
|
|
:else
|
|
(assoc opts :took
|
|
(- (System/currentTimeMillis) t0))))))))
|
|
|
|
(comment
|
|
(wait-for-port "localhost" 80)
|
|
(wait-for-port "localhost" 80 {:timeout 1000})
|
|
(wait-for-port "google.com" 80)
|
|
|
|
(wait-for-path "/tmp/hi")
|
|
(wait-for-path "/tmp/there" {:timeout 1000})
|
|
|
|
)
|