From 4747155d5a488cb6309cc92f926f5d02b87dcf9b Mon Sep 17 00:00:00 2001 From: Case Nelson <case@metabase.com> Date: Mon, 6 Jun 2022 09:29:00 -0600 Subject: [PATCH] Handle deletable state when enabling persistence (#23118) * Handle deletable state when enabling persistence When enabling persistence all models are supposed to be set to creating unless they have been explicitly turned "off". Before, we were only looking for new models without attached PersistedInfos when enabling, but missed deletable PersistedInfos that needed to be re-enabled. It's the correct thing to do during the refresh as you wouldn't want refresh to re-enable but it's incorrect when enabling. * Remove unecessary thread-last --- .../sandbox/api/permissions_test.clj | 2 +- src/metabase/api/card.clj | 2 +- src/metabase/events/persisted_info.clj | 2 +- src/metabase/models/persisted_info.clj | 17 +++++++++++++++-- src/metabase/task/persist_refresh.clj | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/enterprise/backend/test/metabase_enterprise/sandbox/api/permissions_test.clj b/enterprise/backend/test/metabase_enterprise/sandbox/api/permissions_test.clj index 6b8a1ee5572..07ab58c6381 100644 --- a/enterprise/backend/test/metabase_enterprise/sandbox/api/permissions_test.clj +++ b/enterprise/backend/test/metabase_enterprise/sandbox/api/permissions_test.clj @@ -135,7 +135,7 @@ (is (db/exists? GroupTableAccessPolicy :group_id (u/the-id (perms-group/all-users)), :table_id (mt/id :venues)))))))))) (defn- fake-persist-card! [card] - (let [persisted-info (persisted-info/turn-on! (mt/user->id :rasta) card)] + (let [persisted-info (persisted-info/turn-on-model! (mt/user->id :rasta) card)] (db/update-where! PersistedInfo {:card_id (u/the-id card)} :definition (json/encode (persisted-info/metadata->definition diff --git a/src/metabase/api/card.clj b/src/metabase/api/card.clj index 608ec898ccd..ad382124a54 100644 --- a/src/metabase/api/card.clj +++ b/src/metabase/api/card.clj @@ -785,7 +785,7 @@ :database (:name database)}))) (when-not dataset (throw (ex-info (tru "Card is not a model") {:status-code 400}))) - (when-let [persisted-info (persisted-info/turn-on! api/*current-user-id* card)] + (when-let [persisted-info (persisted-info/turn-on-model! api/*current-user-id* card)] (task.persist-refresh/schedule-refresh-for-individual! persisted-info)) api/generic-204-no-content))) diff --git a/src/metabase/events/persisted_info.clj b/src/metabase/events/persisted_info.clj index 4f7c3ca7f5b..6d519db7bd2 100644 --- a/src/metabase/events/persisted_info.clj +++ b/src/metabase/events/persisted_info.clj @@ -33,7 +33,7 @@ (public-settings/persisted-models-enabled) (get-in (Database (:database_id card)) [:options :persist-models-enabled]) (nil? (db/select-one-field :id PersistedInfo :card_id (:id card)))) - (persisted-info/turn-on! (:actor_id card) card)) + (persisted-info/turn-on-model! (:actor_id card) card)) (catch Throwable e (log/warn (format "Failed to process persisted-info event. %s" (:topic event)) e)))) diff --git a/src/metabase/models/persisted_info.clj b/src/metabase/models/persisted_info.clj index e982385f329..9fd2c72ccfb 100644 --- a/src/metabase/models/persisted_info.clj +++ b/src/metabase/models/persisted_info.clj @@ -110,7 +110,7 @@ :creator_id user-id})) (defn ready-unpersisted-models! - "Looks for all models in database and creates a persisted-info ready to be synced." + "Looks for all new models in database and creates a persisted-info ready to be synced." [database-id] (let [cards (db/select Card {:where [:and [:= :database_id database-id] @@ -123,7 +123,7 @@ (comment (ready-unpersisted-models! 183)) -(defn turn-on! +(defn turn-on-model! "Marks PersistedInfo as `creating`, these will at some point be persisted by the PersistRefresh task." [user-id card] (let [card-id (u/the-id card) @@ -138,3 +138,16 @@ :active false, :state "creating", :state_change_at :%now) (db/select-one PersistedInfo :card_id card-id)))] persisted-info)) + +(defn ready-database! + "Sets PersistedInfo state to `creating` for models without a PeristedInfo or those in a `deletable` state. + Will ignore explicitly set `off` models." + [database-id] + (db/update! PersistedInfo + {:where [:and + [:= :database_id database-id] + [:= :state "deletable"]] + :set {:active false, + :state "creating", + :state_change_at :%now}}) + (ready-unpersisted-models! database-id)) diff --git a/src/metabase/task/persist_refresh.clj b/src/metabase/task/persist_refresh.clj index 99d8d74b580..0fd614a863f 100644 --- a/src/metabase/task/persist_refresh.clj +++ b/src/metabase/task/persist_refresh.clj @@ -297,7 +297,7 @@ (u/format-color 'green "Scheduling persistence refreshes for database %d: trigger: %s" (u/the-id database) (.. ^Trigger tggr getKey getName))) - (persisted-info/ready-unpersisted-models! (u/the-id database)) + (persisted-info/ready-database! (u/the-id database)) (try (task/add-trigger! tggr) (catch ObjectAlreadyExistsException _e (log/info -- GitLab