Heroku - 在"主要"中使用Stuart Sierra组件错误的Clojure App

rbb*_*rbb 9 clojure heroku

我正在尝试在我的heroku dyno上开始我的clojure应用程序,但我在stuartsierra.component/start中继续得到错误.

(defrecord Listener [listener]
  component/Lifecycle
  (start [component]
    (assoc component :listener (yada/listener
                                 ["/"
                                  [(view/view-route)
                                   routes/route-handler
                                   ["public/" (new-directory-resource (io/file "target/cljsbuild/public") {})]
                                   [true (as-resource nil)]]]
                                 (or (env :port) (get (read-config "resources/config.edn" {:profile :dev}) :webserver))
                                 )))
  (stop [component]
    (when-let [close (-> component :listener :close)]
      (close))
    (assoc component :listener nil)))

(defn new-system []
  (component/system-map
    :listener (map->Listener {})
    ))

(def system nil)

(defn init []
  (alter-var-root #'system
                  (constantly (new-system))))

(defn start []
  (alter-var-root #'system component/start))

(defn stop []
  (alter-var-root #'system
                  (fn [s] (when s (component/stop s)))))

(defn go []
  (init)
  (start))

(defn reset []
  (stop)
  (refresh :after 'web.core/go))

(defn -main
  [& [port]]
  (component/start (new-system))
  (println "System Started")
  @(promise))
Run Code Online (Sandbox Code Playgroud)

这是我的所有stuartsierra.component代码的核心文件.当我在我的笔记本电脑上本地运行它lein repl然后(go)以及我刚刚做的时候,这一切都完美无缺lein run.所以当我把它推到heroku dyno时,我很困惑为什么它不起作用.

我得到的错误是

Exception in thread "main" clojure.lang.ExceptionInfo: Error in component :listener in system com.stuartsierra.component.SystemMap calling #'com.stuartsierra.component/start {:reason :com.stuartsierra.component/component-function-threw-exception, :function #'com.stuartsierra.component/start, :system-key :listener, :component #web.core.Listener{:listener nil}, :system #<SystemMap>}, compiling:(/tmp/form-init9049917434081554913.clj:1:73)
Run Code Online (Sandbox Code Playgroud)

这是告诉我,我:listenernilsystem-map.当我检查本地(这样做lein repl (go)的)(keys system)(:listener)这是很好的,这样意味着监听器启动,并在系统中.

当我这样做时,(-> system :listener)我得到的#web.core.Listener{:listener {:port 3300, :close #object[yada.aleph$listener$fn__21671 0xa5d4865 "yada.aleph$listener$fn__21671@a5d4865"], :server #object[aleph.netty$start_server$reify__13574 0x3cc9a232 "aleph.netty$start_server$reify__13574@3cc9a232"]}}是完美的,因为端口已加载(3300)并且服务器已启动.

这使得至于为什么这一切更令人困惑的:listenernil在我的应用程序的Heroku

任何帮助将非常感激.谢谢

jr0*_*ket 1

Heroku 动态地将端口分配给web:进程。应使用 Heroku 环境变量将该端口的值传递给 Clojure 代码$PORT

所以Procfile应该包含端口变量

web: lein with-profile production trampoline run -m web.core $PORT
Run Code Online (Sandbox Code Playgroud)

该端口值应从命名空间-main中的函数传递到组件中web.core

如果文件中包含:uberjar-name "webapp.jar"和设置,Heroku 将构建一个 uberjar(您的 Clojure 应用程序 + Clojure 本身)。 :min-lein-version "2.0.0"project.clj

然后可以使用 java 命令来运行 Clojure 应用程序,使用 Heroku 构建的 uberjar 并使用更少的资源

web: java -jar target/webapp.jar $PORT
Run Code Online (Sandbox Code Playgroud)

参考: