Otann / morse

📡 Clojure interface for Telegram Bot API
Eclipse Public License 1.0
257 stars 48 forks source link

Long-polling HTTP request timed out, stopping polling #40

Open dark4eg opened 6 years ago

dark4eg commented 6 years ago

Long-polling

sample code from README.md

(require '[morse.polling :as p])
(def channel (p/start token handler))

returned

ERROR morse.polling - HTTP request timed out, stopping polling

Otann commented 6 years ago

Thanks! I'll look into it soon.

As a temporary workaround, try maybe adding a timeout?

(def channel (p/start token handler {:timeout 10}))
KGOH commented 5 years ago

I have the same issue. Adding {:timeout 10} didn't help

jakuzure commented 5 years ago

Same thing happened to me, any news on this issue yet?

KGOH commented 5 years ago

Same thing happened to me, any news on this issue yet?

Here https://github.com/Otann/morse/blob/bbb2efc6a8eb17603a56121fbe10e1592ce5d8ee/src/morse/polling.clj#L43 I've added (System/exit 1) right after (close! updates), to crash app instead of freeze. This is a bad solution, but I haven't come up with anything better to prevent freezes :(

You can create file polling_patch.clj:

(ns morse.polling-patch
  (:require [morse.polling]))

(in-ns 'morse.polling)

(defn create-producer
  "Passed channel should be always empty.
   Close it to stop long-polling.
   Returns channel with updates from Telegram"
  [running token opts]
  (let [updates (a/chan)
        ;; timeout for Telegram API in seconds
        timeout (or (:timeout opts) 1)]
    (go-loop [offset 0]
      (let [;; fix for JDK bug https://bugs.openjdk.java.net/browse/JDK-8075484
            ;; introduce additional timeout 10 times more that telegram's one
            wait-timeout (a/go (a/<! (a/timeout (* 1000 timeout 10)))
                               ::wait-timeout)
            response     (api/get-updates-async token (assoc opts :offset offset))
            [data _] (a/alts! [running response wait-timeout])]
        (case data
          ;; running got closed by the user
          nil
          (do (log/info "Stopping Telegram polling...")
              (close! wait-timeout)
              (close! updates))

          ::wait-timeout
          (do (log/error "HTTP request timed out, stopping polling")
              (close! running)
              (close! updates)
              (log/fatal "ABORT")
              (System/exit 1))

          ::api/error
          (do (log/warn "Got error from Telegram API, stopping polling")
              (close! running)
              (close! updates))

          (do (close! wait-timeout)
              (doseq [upd data] (>! updates upd))
              (recur (new-offset data offset))))))
    updates))

(in-ns 'morse.polling-patch)

And then require this morse.polling-patch somewhere in your project

jakuzure commented 5 years ago

Thanks for the quick reply, I'll try it out!

Bost commented 4 years ago

I've added (System/exit 1) right after (close! updates), to crash app instead of freeze.

Thanks for the workaround. It really "solved" my problem. And I use it also for the ::api/error branch. Anyway, does anybody have an explanation why these problem arise in the first place?

Bost commented 4 years ago

FWIW on ::api/error I get:

SocketException The transport's socket appears to have lost its connection to the nREPL server
    nrepl.transport/bencode/fn--9182/fn--9183 (transport.clj:108)
    nrepl.transport/bencode/fn--9182 (transport.clj:108)
    nrepl.transport/fn-transport/fn--9150 (transport.clj:55)
    clojure.core/binding-conveyor-fn/fn--5739 (core.clj:2030)
    java.util.concurrent.FutureTask.run (FutureTask.java:264)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:628)
    java.lang.Thread.run (Thread.java:834)
Bye for now!
dmisiuk commented 1 year ago

Maybe it will be useful for somebody. 0.3.1 - the last version that works with long-polling without this issue. 0.3.2 was rewritten to use async that fails with time-out unfrotufately.