Logic related to initializing plugins, i.e. running the Note that this is not the same thing as initializing drivers -- drivers are initialized lazily when first needed; this step on the other hand runs at launch time and sets up that lazy load logic. | (ns metabase.plugins.initialize (:require [metabase.plugins.dependencies :as deps] [metabase.plugins.init-steps :as init-steps] [metabase.plugins.lazy-loaded-driver :as lazy-loaded-driver] [metabase.util :as u] [metabase.util.log :as log] [metabase.util.malli :as mu])) |
(defonce ^:private initialized-plugin-names (atom #{})) | |
(defn- init! [{:keys [add-to-classpath!], init-steps :init, {plugin-name :name} :info, driver-or-drivers :driver, :as info}] {:pre [(string? plugin-name)]} (when (deps/all-dependencies-satisfied? @initialized-plugin-names info) ;; for each driver, if it's lazy load, register a lazy-loaded placeholder driver (let [drivers (u/one-or-many driver-or-drivers)] (doseq [{:keys [lazy-load], :or {lazy-load true}, :as driver} drivers] (when lazy-load (lazy-loaded-driver/register-lazy-loaded-driver! (assoc info :driver driver)))) ;; if *any* of the drivers is not lazy-load, initialize it now (when (some false? (map :lazy-load drivers)) (when add-to-classpath! (add-to-classpath!)) (init-steps/do-init-steps! init-steps))) ;; record this plugin as initialized and find any plugins ready to be initialized because depended on this one ! ;; ;; Fun fact: we already have the `plugin-initialization-lock` if we're here so we don't need to worry about ;; getting it again (let [plugins-ready-to-init (deps/update-unsatisfied-deps! (swap! initialized-plugin-names conj plugin-name))] (when (seq plugins-ready-to-init) (log/debug (u/format-color 'yellow (format "Dependencies satisfied; these plugins will now be loaded: %s" (mapv (comp :name :info) plugins-ready-to-init))))) (doseq [plugin-info plugins-ready-to-init] (init! plugin-info))) :ok)) | |
(defn- initialized? [{{plugin-name :name} :info}] (@initialized-plugin-names plugin-name)) | |
Initialize plugin using parsed info from a plugin manifest. Returns truthy if plugin was successfully initialized; falsey otherwise. | (mu/defn init-plugin-with-info! [info :- [:map [:info [:map [:name :string] [:version :string]]]]] (or (initialized? info) (locking initialized-plugin-names (or (initialized? info) (init! info))))) |