Reason for skipping AOT?

This isn’t specific to noir but one scenario you might want to skip AOT for a given namespace is when deploying your code to a PaaS provider such as heroku.

Heroku performs AOT compilation of your code by default so consider this snippet in your server.clj:

(db/connect! (System/getenv "DB_URL"))

(defn start [port]
  (run-jetty app {:port port :join? false :max-threads 100}))

In principle this code seems harmless and will work locally regardless of it being AOT-compiled.

However during compilation on heroku, the environment variable “DB_URL” isn’t available yet so the connect! statement above will try to connect to nil and throw an exception.

Skipping AOT compilation of this namespace is one way of preventing this.

Another, and my preferred approach at the moment would be to change it slightly to this:

(defn bootstrap! []
  (db/connect! (System/getenv "DB_URL")))

(defn start [port]
  (bootstrap!)  
  (run-jetty app {:port port :join? false :max-threads 100}))

That way it’s a little clearer what your intention is and you avoid attempting a database connection during compilation.

I learned this the hard way and documented it in this blog post.

Hope this is useful.

Leave a Comment

tech