Hi again! Not posting for too much long.
Well, this time we will explore the clojure’s ability to load arbitrary files as code.
This is such an amazing feature, but you should be careful. Don’t start reading anyones files and evaluating them into your app. Be wise and use it for specific situation like this: I wanted to load a bunch of configurations (and even funtion calls) depending on the environment my app is running.
To do the conditional evaluation, I decided to add an extra key to :immutant
entry in my project definition. The entry :env
is an arbitrary configuration value. Lets take a look:
In this sample project.clj
you find :immutant
directly under the project definition. This key is used to, regardless of the environment, inform immutant which funtion to call when your app starts up. In this case tserver.init/init
, that we will further analyze.
Pay attention to the :env
entry. It is located under :immutant
that is under [:profiles :dev]
. Here enters a leiningen’s profiles feature. Where you can even specify dependencies or anything you want by profile. In this case, the immutant config is being configured by profile.
Why not simply load a config per profile?
Because you can combine n profiles at the sime time. So, which one to use as the enviroment reference? That is why I decided to use an specific entry for that.
Below the initial function being called by immutant. Here goes intereting stuff. One of them is the use of in-ns
, use
and require
. This is awesome because I’m calling what could be “equivalent to a java import” in the middle of a clojure file, and even better: I’m doing this to another namespace that differs from the code that is actually calling the “imports”.
So, in-ns
will create the namespace tserver.config
and “import” the appropriate functions and namespaces.
The init
funtion here will simply call the load-config
, that is in charge of loading the config file. Look:
And finally, our config file containing the required configurations. It can be anything you need.
Now, to deploy and start the app with the given profile we simply do:
Voila! This will load your dev.clj
file and set up your queues, jobs, web-context, whatever you want. This is useful, and I would risk to say mandatory today. You probably have sereval environments where your app resides before going to prodution, and each of them with different names, addresses, pool sizes, queue names, database to connect, etc. And you can easily give to your app the intelligence to load what is more appropriate.