diff --git a/README.md b/README.md index f0b2d8e..c586e17 100644 --- a/README.md +++ b/README.md @@ -346,6 +346,47 @@ In the pod client: nil ``` +#### Deferred namespace loading + +When your pod exposes multiple namespaces that can be used independently from +each other, consider implementing the `load-ns` op which allows the pod client +to load the namespace and process the client side code when it is loaded using +`require`. This will speed up the initial setup of the pod using `load-pod`. + +In `describe` the pod will mark the namespaces as deferred: + +``` clojure +{"name" "pod.lispyclouds.deferred-ns" + "defer" "true"} +``` + +When the user requires the namespace with `(require +'[pod.lispyclouds.deferred-ns])` the pod client will then send a message: + +``` clojure +{"op" "load-ns" + "ns" "pod.lispyclouds.deferred-ns" + "id "..."} +``` + +upon which the pod will reply with the namespace data: + +``` clojure +{"name" "pod.lispyclouds.deferred-ns" + "vars" [{"name" "myfunc" "code" "(defn my-func [])"}]} +``` + +If a deferred namespace depends on another deferred namespace, provide explicit +`require`s in `code` segments: + +``` clojure +{"name" "pod.lispyclouds.another-deferred-ns" + "vars" + [{"name" "myfunc" + "code" "(require '[pod.lispyclouds.deferred-ns :as dns]) + (defn my-func [] (dns/x))"}]} +``` + #### Async Asynchronous functions can be implemented using callbacks. diff --git a/src/babashka/pods/impl.clj b/src/babashka/pods/impl.clj index d63911e..e9f978c 100644 --- a/src/babashka/pods/impl.clj +++ b/src/babashka/pods/impl.clj @@ -189,8 +189,8 @@ name-sym (symbol name-str) vars (get namespace "vars") vars (bencode->vars pod name-str vars) - lazy? (some-> namespace (get-maybe-string "lazy") (= "true"))] - [name-sym vars lazy?])) + defer? (some-> namespace (get-maybe-string "defer") (= "true"))] + [name-sym vars defer?])) (defn load-pod ([pod-spec] (load-pod pod-spec nil)) diff --git a/src/babashka/pods/jvm.clj b/src/babashka/pods/jvm.clj index 9d524a0..9dfef6b 100644 --- a/src/babashka/pods/jvm.clj +++ b/src/babashka/pods/jvm.clj @@ -42,16 +42,14 @@ (intern (create-ns (symbol (namespace sym))) (symbol (name sym)))))}) - namespaces (:namespaces pod) - load? (contains? (:ops pod) :load-ns)] - (when load? - (swap! namespaces-to-load - merge - (into {} - (keep (fn [[ns-name _ lazy?]] - (when lazy? - [ns-name pod])) - namespaces)))) + namespaces (:namespaces pod)] + (swap! namespaces-to-load + merge + (into {} + (keep (fn [[ns-name _ defer?]] + (when defer? + [ns-name pod])) + namespaces))) (doseq [[ns-sym vars lazy?] namespaces :when (not lazy?)] (process-namespace {:name ns-sym :vars vars})) diff --git a/src/babashka/pods/sci.clj b/src/babashka/pods/sci.clj index d41b002..b9ab964 100644 --- a/src/babashka/pods/sci.clj +++ b/src/babashka/pods/sci.clj @@ -40,12 +40,10 @@ v) v))))})) namespaces (:namespaces pod) - load? (contains? (:ops pod) :load-ns) - namespaces-to-load (when load? - (set (keep (fn [[ns-name _ lazy?]] - (when lazy? - ns-name)) - namespaces)))] + namespaces-to-load (set (keep (fn [[ns-name _ defer?]] + (when defer? + ns-name)) + namespaces))] (when (seq namespaces-to-load) (let [load-fn (fn load-fn [{:keys [:namespace]}] (when (contains? namespaces-to-load namespace) diff --git a/test-pod/pod/test_pod.clj b/test-pod/pod/test_pod.clj index 9b0ab17..fdc72d7 100644 --- a/test-pod/pod/test_pod.clj +++ b/test-pod/pod/test_pod.clj @@ -82,11 +82,10 @@ "code" "(defn read-other-tag [x] [x x])"}] dependents)} {"name" "pod.test-pod.loaded" - "lazy" "true"} + "defer" "true"} {"name" "pod.test-pod.loaded2" - "lazy" "true"}] - "ops" {"shutdown" {} - "load-ns" {}}}) + "defer" "true"}] + "ops" {"shutdown" {}}}) (recur)) :invoke (let [var (-> (get message "var") read-string