Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Heroku - Clojure App using Stuart Sierra Component Error in "main"

Tags:

heroku

clojure

I am trying to start my clojure application on my heroku dyno but I keep getting and error in my 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))

This is my core file with all my stuartsierra.component code. This all works perfectly when I run it locally on my laptop doing lein repl and then (go) and also when I just do lein run. So I am confused as to why it doesn't work when I push this to the heroku dyno.

The error I get is

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)

This is telling me that my :listener is nil in the system-map. When I check locally (doing lein repl (go)) in (keys system) is (:listener) which is good so that means that the listener is starting and is in the system.

When I do (-> system :listener) I get #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"]}} which is perfect as the port has loaded up (3300) and the server has started.

This makes it all the more confusing as to why the :listener is nil in my heroku app

Any help would be much appreciated. Thanks

like image 864
rbb Avatar asked Mar 18 '26 22:03

rbb


1 Answers

Heroku dynamically assigns ports to web: processes. The value of that port should be passed to the Clojure code using the Heroku environment variable $PORT

So the Procfile should include the port variable

web: lein with-profile production trampoline run -m web.core $PORT

This port value should be passed into the component from the -main function in the web.core namespace.

As Heroku will build an uberjar (your Clojure application + Clojure itself) if the :uberjar-name "webapp.jar" and :min-lein-version "2.0.0" settings are included in project.clj file.

The java command can then be used to run the Clojure application, using the uberjar that Heroku builds and using fewer resources

web: java -jar target/webapp.jar $PORT

Reference:

  • https://devcenter.heroku.com/articles/procfile#the-web-process-type
  • https://github.com/technomancy/leiningen/blob/stable/sample.project.clj
like image 157
jr0cket Avatar answered Mar 20 '26 15:03

jr0cket



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!