    by one of the consumer functions
    Returns the pool"
   [pool data]
-   (.put ^BlockingQueue (:queue pool) data)
+   (when-not (.offer ^BlockingQueue (:queue pool) data 5 TimeUnit/SECONDS)
+     (error "Thread load publish queue is full, blocking till a slot becomes available")
+     (.put ^BlockingQueue (:queue pool) data)
+     (info "Unblocked"))
+
    pool)
 
 (defn bulk-get!

  "Important: This function is not threadsafe and should only be called from a single producer
   The reason is that the .size of the queue is checked, and if enough space .addAll is called,
   otherwise .put is used"
  [{:keys [^BlockingQueue queue limit]} data-coll]
  (if (> (.size queue) limit)
    (.addAll queue data-coll)
    (doseq [data data-coll]
      (.put queue data))))

(defn shutdown-pool 
  "Shutdown the ExecutorService used and wait for termination timeout milliseconds, if the threads did not all terminate, the pool is shutdown forcefully"

(defn get-queue-data! 
  "Blocks till data is available on the queue and returns the data, queue must be BlockingQueue"
  [^BlockingQueue queue]
  (if-let [v (.poll queue 5 TimeUnit/SECONDS)]
    v
    (do
      (debug "No data from queue, blocking till data becomes available")
      (try
        (.take queue)
        (finally
          (debug "Unblocked"))))))

(defn call-on-fail 
  "Only calls init if the return of stop is not :terminate or :fail"
