-
-
Notifications
You must be signed in to change notification settings - Fork 178
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
envand returns it. - (destroy-pod pod)
-
Prepares the
podso 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
bodyexpressions in thepodand return the result. Thebodyexpressions 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
exprexpression in thepodand return the result. Theexprexpression 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/requireof the namespacensin the givenpod. - (.invoke pod ^String f args*)
-
Invokes the function denoted by
f(of the form"namespace/name") with the givenargsand 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
sizepods available. Returns a pool service object. - (pool-service)
-
Invoking a
pool-serviceobject with no arguments obtains a reference to the current active pod in the pool. - (pool-service :refresh)
-
Invoking a
pool-serviceobject with the:refreshargument destroys the current active pod and replaces it with another from the pool. - (pool-service :shutdown)
-
Invoking a
pool-serviceobject with the:shutdownargument 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
