diff --git a/resources/migrations/000_migrations.yaml b/resources/migrations/000_migrations.yaml index 679fa64323d72eb150e64a77996922766f1be739..bd0795c090b07ffba6ed8418d43b6da27cdb70e7 100644 --- a/resources/migrations/000_migrations.yaml +++ b/resources/migrations/000_migrations.yaml @@ -3828,88 +3828,4 @@ databaseChangeLog: - dropForeignKeyConstraint: baseTableName: raw_table constraintName: fk_rawtable_ref_database - remarks: 'This FK prevents deleting databases even though RAW_TABLE is no longer used. The table is still around to support downgrades, but the FK reference is no longer needed.' - - changeSet: - id: 65 - author: sbelak - comment: 'Added 0.26.0' - changes: - - createTable: - tableName: computation_job - remarks: 'Stores submitted async computation jobs.' - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - constraints: - deferrable: false - foreignKeyName: fk_computation_job_ref_user_id - initiallyDeferred: false - references: core_user(id) - name: creator_id - type: int - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - column: - name: type - type: varchar(254) - constraints: - nullable: false - - column: - name: status - type: varchar(254) - constraints: - nullable: false - - createTable: - tableName: computation_job_result - remarks: 'Stores results of async computation jobs.' - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - constraints: - deferrable: false - foreignKeyName: fk_computation_result_ref_job_id - initiallyDeferred: false - nullable: false - references: computation_job(id) - name: job_id - type: int - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - column: - name: permanence - type: varchar(254) - constraints: - nullable: false - - column: - name: payload - type: text - constraints: - nullable: false \ No newline at end of file + remarks: 'This FK prevents deleting databases even though RAW_TABLE is no longer used. The table is still around to support downgrades, but the FK reference is no longer needed.' \ No newline at end of file diff --git a/src/metabase/api/x_ray.clj b/src/metabase/api/x_ray.clj index ddde0670554c875a0179342f6fcfedbaba588728..dfd7c11e93612fba2d13baa1aaac1383637e5bb1 100644 --- a/src/metabase/api/x_ray.clj +++ b/src/metabase/api/x_ray.clj @@ -2,12 +2,10 @@ (:require [compojure.core :refer [GET PUT]] [metabase.api.common :as api] [metabase.feature-extraction - [async :as async] [core :as fe] [costs :as costs]] [metabase.models [card :refer [Card]] - [computation-job :refer [ComputationJob]] [field :refer [Field]] [metric :refer [Metric]] [segment :refer [Segment]] @@ -58,26 +56,6 @@ max_computation_cost)}) fe/x-ray)) -(api/defendpoint GET "/async/table/:id" - "Get x-ray for a `Tield` with ID." - [id max_query_cost max_computation_cost] - {max_query_cost MaxQueryCost - max_computation_cost MaxComputationCost} - (api/check-403 (costs/enable-xrays)) - (let [table (api/read-check Table id)] - {:job-id (async/compute - #(->> table - (fe/extract-features {:max-cost (max-cost max_query_cost - max_computation_cost)}) - fe/x-ray))})) - -(api/defendpoint GET "/async/:id" - "Get x-ray for a `Tield` with ID." - [id] - (->> id - (api/read-check ComputationJob) - async/result)) - (api/defendpoint GET "/segment/:id" "Get x-ray for a `Segment` with ID." [id max_query_cost max_computation_cost] diff --git a/src/metabase/cmd/load_from_h2.clj b/src/metabase/cmd/load_from_h2.clj index fd16c8b653c6597da63090a646d8752d6009b33b..c232068fe9ef386af399850954765f11063e2465 100644 --- a/src/metabase/cmd/load_from_h2.clj +++ b/src/metabase/cmd/load_from_h2.clj @@ -29,8 +29,6 @@ [card-label :refer [CardLabel]] [collection :refer [Collection]] [collection-revision :refer [CollectionRevision]] - [computation-job :refer [ComputationJob]] - [computation-job-result :refer [ComputationJobResult]] [dashboard :refer [Dashboard]] [dashboard-card :refer [DashboardCard]] [dashboard-card-series :refer [DashboardCardSeries]] @@ -100,8 +98,6 @@ CollectionRevision DashboardFavorite Dimension - ComputationJob - ComputationJobResult ;; migrate the list of finished DataMigrations as the very last thing (all models to copy over should be listed above this line) DataMigrations]) diff --git a/src/metabase/feature_extraction/async.clj b/src/metabase/feature_extraction/async.clj deleted file mode 100644 index fe0338a92a3905206a2265374f6c2d1cc545e116..0000000000000000000000000000000000000000 --- a/src/metabase/feature_extraction/async.clj +++ /dev/null @@ -1,70 +0,0 @@ -(ns metabase.feature-extraction.async - (:require [metabase.api.common :as api] - [metabase.models - [computation-job :refer [ComputationJob]] - [computation-job-result :refer [ComputationJobResult]]] - [toucan.db :as db])) - -(defonce ^:private running-jobs (atom {})) - -(def ^{:arglists '([job])} done? - "Is the computation job done?" - (comp some? #{:done :error} :status)) - -(def ^{:arglists '([job])} running? - "Is the computation job still running?" - (comp some? #{:running} :status)) - -(defn- save-result - [{:keys [id]} payload] - (db/transaction - (db/insert! ComputationJobResult - :job_id id - :permanence :temporary - :payload payload) - (db/update! ComputationJob id :status :done)) - (swap! running-jobs dissoc id)) - -(defn- save-error - [{:keys [id]} error] - (db/transaction - (db/insert! ComputationJobResult - :job_id id - :permanence :temporary - :payload (Throwable->map error)) - (db/update! ComputationJob id :status :error)) - (swap! running-jobs dissoc id)) - -(defn cancel - "Cancel computation job (if still running)." - [{:keys [id] :as job}] - (when (running? job) - (future-cancel (@running-jobs id)) - (swap! running-jobs dissoc id) - (db/update! ComputationJob id :status :canceled))) - -(defn compute - "Compute closure `f` asynchronously. Returns id of the associated computation - job." - [f] - (let [job (db/insert! ComputationJob - :creator_id api/*current-user-id* - :status :running - :type :simple-job) - id (:id job)] - (swap! running-jobs assoc id (future - (try - (save-result job (f)) - (catch Exception e - (save-error job e))))) - id)) - -(defn result - "Get result of an asynchronous computation job." - [job] - (if (done? job) - (if-let [result (db/select-one ComputationJobResult :job_id (:id job))] - {:status (:status job) - :result (:payload result)} - {:status :result-not-available}) - {:status (:status job)})) diff --git a/src/metabase/models/computation_job.clj b/src/metabase/models/computation_job.clj deleted file mode 100644 index c3728ff9ef902dff71217e992839d0fb06905740..0000000000000000000000000000000000000000 --- a/src/metabase/models/computation_job.clj +++ /dev/null @@ -1,22 +0,0 @@ -(ns metabase.models.computation-job - (:require [metabase.api.common :as api] - [metabase.models.interface :as i] - [metabase.util :as u] - [toucan.models :as models])) - -(models/defmodel ComputationJob :computation_job) - -(defn- creator? - [{:keys [creator_id]}] - (= creator_id api/*current-user-id*)) - -(u/strict-extend (class ComputationJob) - models/IModel - (merge models/IModelDefaults - {:types (constantly {:status :keyword - :type :keyword}) - :properties (constantly {:timestamped? true})}) - i/IObjectPermissions - (merge i/IObjectPermissionsDefaults - {:can-read? creator? - :can-write? creator?})) diff --git a/src/metabase/models/computation_job_result.clj b/src/metabase/models/computation_job_result.clj deleted file mode 100644 index d1397726a6946164b7aa1a8c41d24f2fa9f39082..0000000000000000000000000000000000000000 --- a/src/metabase/models/computation_job_result.clj +++ /dev/null @@ -1,13 +0,0 @@ -(ns metabase.models.computation-job-result - (:require [metabase.models.interface :as i] - [metabase.util :as u] - [toucan.models :as models])) - -(models/defmodel ComputationJobResult :computation_job_result) - -(u/strict-extend (class ComputationJobResult) - models/IModel - (merge models/IModelDefaults - {:types (constantly {:permanence :keyword - :payload :json}) - :properties (constantly {:timestamped? true})})) diff --git a/src/metabase/task/cleanup_temporary_computation_job_results.clj b/src/metabase/task/cleanup_temporary_computation_job_results.clj deleted file mode 100644 index 0e76c7a2ea05b395ee15641508da5ae136b37807..0000000000000000000000000000000000000000 --- a/src/metabase/task/cleanup_temporary_computation_job_results.clj +++ /dev/null @@ -1,45 +0,0 @@ -(ns metabase.task.cleanup-temporary-computation-job-results - "Cleanup of old async computation results." - (:require [clj-time.core :as t] - [clojurewerkz.quartzite - [jobs :as jobs] - [triggers :as triggers]] - [clojurewerkz.quartzite.schedule.daily-interval :as interval] - [metabase.task :as task] - [toucan.db :as db])) - -(def ^:private temporary-result-lifetime (t/days 3)) - -(defn- cleanup-temporary-results! - [] - (db/delete! 'ComputationJobResult - :created_at [:< (-> (t/now) - (t/minus temporary-result-lifetime) - str)])) - -(def ^:private ^:const cleanup-job-key "metabase.task.cleanup-temporary-computation-job-results.job") -(def ^:private ^:const cleanup-trigger-key "metabase.task.cleanup-temporary-computation-job-results.trigger") - -(jobs/defjob Cleanup - [ctx] - (cleanup-temporary-results!)) - -(defonce ^:private cleanup-job (atom nil)) -(defonce ^:private cleanup-trigger (atom nil)) - -(defn task-init - "Automatically called during startup; start the job for sending pulses." - [] - (reset! cleanup-job (jobs/build - (jobs/of-type Cleanup) - (jobs/with-identity (jobs/key cleanup-job-key)))) - (reset! cleanup-trigger (triggers/build - (triggers/with-identity - (triggers/key cleanup-trigger-key)) - (triggers/start-now) - (triggers/with-schedule - ;; once per day at 3AM - (interval/schedule - (interval/starting-daily-at - (interval/time-of-day 03 00 00)))))) - (task/schedule-task! @cleanup-job @cleanup-trigger)) diff --git a/test/metabase/feature_extraction/async_test.clj b/test/metabase/feature_extraction/async_test.clj deleted file mode 100644 index 661625689fac5ebb5ce579a8e82cde4d8beff267..0000000000000000000000000000000000000000 --- a/test/metabase/feature_extraction/async_test.clj +++ /dev/null @@ -1,31 +0,0 @@ -(ns metabase.feature-extraction.async-test - (:require [expectations :refer :all] - [metabase.feature-extraction.async :refer :all] - [metabase.models.computation-job :refer [ComputationJob]])) - -(expect - true - (let [job-id (compute (constantly 1))] - (Thread/sleep 100) - (done? (ComputationJob job-id)))) - -(expect - true - (let [job-id (compute #(do (Thread/sleep 10000) nil))] - (Thread/sleep 100) - (running? (ComputationJob job-id)))) - -(expect - [true false false] - (let [job-id (compute #(do (Thread/sleep 100000) nil))] - (Thread/sleep 100) - (let [r? (running? (ComputationJob job-id))] - (cancel (ComputationJob job-id)) - [r? (done? (ComputationJob job-id)) (running? (ComputationJob job-id))]))) - -(expect - {:status :done - :result 1} - (let [job-id (compute (constantly 1))] - (Thread/sleep 100) - (result (ComputationJob job-id))))