-
-
Notifications
You must be signed in to change notification settings - Fork 179
Pods
Pods are only relevant to you if you want to extend Boot with your own tasks. If you're just getting started with Boot you probably don't need to worry about them.
Boot's primary purpose is to bootstrap Clojure applications. This involves bringing up the JVM, starting a Clojure runtime, and fetching and loading JAR dependencies from Maven repositories.
Automatic resolution of dependencies is great, but you can easily end up in dependency hell if you aren't careful. Boot provides a mechanism by which dependencies can be isolated from each other: we call this technique pods.
Pods are Clojure runtimes loaded from separate class loaders, built using the excellent shimdandy library. Pods are:
-
First-class – create anonymous pods, pass them to functions, etc.
-
Isolated – pods can be created with arbitrary dependencies and classpaths, and these do not affect the environment outside the pod.
-
Self-contained – pods are completely independent Clojure runtimes.
The primary avenue of attack when faced with dependency hell is isolation. Dependencies are separated into logically independent subsets that provide specific functionality. Pods are created and these dependencies loaded in them. Expressions can then be evaluated in these pods to do work or compute.
Note: pods are separate Clojure runtimes. Clojure objects created in one pod can't be used in another (each runtime has its own protocol implementations and class definitions which are not accessible from other runtimes).
The pods API is defined in the boot.pod namespace. This namespace contains functions useful for managing dependencies and classpaths. It is available in any pod.
- (make-pod env)
-
Creates a new pod with the given boot environment
env
and returns it. - (destroy-pod pod)
-
Prepares the
pod
so it can be collected as garbage by the JVM.Note that this won't shut down threads running in the pod other than the Clojure agent pool, and running threads can prevent the pod from being reaped by the garbage collector.
- (with-eval-in pod body*)
-
Evaluate the
body
expressions in thepod
and return the result. Thebody
expressions are templates.The body and result must be able to be printed by pr-str and then read by read-string.
- (with-call-in pod expr)
-
Evaluate the
expr
expression in thepod
and return the result. Theexpr
expression is a template. It must be a list whose first item is a namespace-qualified symbol (the function to call).The expr and result must be able to be printed by pr-str and then read by read-string.
- (.require pod ^String ns)
-
Does
clojure.core/require
of the namespacens
in the givenpod
. - (.invoke pod ^String f args*)
-
Invokes the function denoted by
f
(of the form"namespace/name"
) with the givenargs
and returns the result.The args and result must not be Clojure objects.
Pods can take some time to warm up, so it's sometimes useful to maintain a pool of pods in reserve, ready for use.
- (pod-pool env :size ... :init ... :destroy ...)
-
Creates a pool of pods such that there will always be
size
pods available. Returns a pool service object. - (pool-service)
-
Invoking a
pool-service
object with no arguments obtains a reference to the current active pod in the pool. - (pool-service :refresh)
-
Invoking a
pool-service
object with the:refresh
argument destroys the current active pod and replaces it with another from the pool. - (pool-service :shutdown)
-
Invoking a
pool-service
object with the:shutdown
argument destroys all pods in the pool and shuts down the service.
Pods are bootstrapped with the environment passed to the
make-pod
function. Usually this env will have different dependencies from the
parent pod. However, most of the time you will want to pass the current Maven
repo settings to the pod (eg. repositories, mirrors, etc.), and most of the
work done in pods needs access to things on the classpath of the parent. Thus,
in almost every case you want to do something like this:
(make-pod
(update-in (get-env) [:dependencies]
conj '[foo/bar "1.2.3"]))
rather than something like this:
(make-pod {:dependencies [[foo/bar "1.2.3"]]})
You can find other developers and users in the #hoplon
channel on freenode IRC or the boot slack channel.
If you have questions or need help, please visit the Discourse site.
- Environments
- Boot environment
- Java environment
- Tasks
- Built-ins
- Third-party
- Tasks Options
- Filesets
- Target Directory
- Pods
- Boot Exceptions
- Configuring Boot
- Updating Boot
- Setting Clojure version
- JVM Options
- S3 Repositories
- Scripts
- Task Writer's Guide
- Require inside Tasks
- Boot for Leiningen Users
- Boot in Leiningen Projects
- Repl reloading
- Repository Credentials and Deploying
- Snippets
- Troubleshooting
- FAQ
- API docs
- Core
- Pod
- Util