Unverified Commit 9a88c21e authored by Marius van den Beek's avatar Marius van den Beek Committed by GitHub
Browse files

Merge pull request #14108 from mvdbeek/probably_fix_test_delete_cancels_job_test

Fix deleting jobs when deleting datasets
parents 8aceb264 0be561d6
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -270,7 +270,7 @@ class DatasetAssociationManager(
        """
        super().delete(item, flush=flush)
        if stop_job:
            self.stop_creating_job(item)
            self.stop_creating_job(item, flush=flush)
        return item

    def purge(self, dataset_assoc, flush=True):
@@ -281,13 +281,14 @@ class DatasetAssociationManager(
        # TODO: this check may belong in the controller
        self.dataset_manager.error_unless_dataset_purge_allowed()

        # We need to ignore a potential flush=False here and force the flush
        # We need to ignore a potential flush=False here if jobs are not tracked in the database,
        # so that job cleanup associated with stop_creating_job will see
        # the dataset as purged.
        super().purge(dataset_assoc, flush=True)
        flush_required = not self.app.config.track_jobs_in_database
        super().purge(dataset_assoc, flush=flush or flush_required)

        # stop any jobs outputing the dataset_assoc
        self.stop_creating_job(dataset_assoc)
        self.stop_creating_job(dataset_assoc, flush=True)

        # more importantly, purge underlying dataset as well
        if dataset_assoc.dataset.user_can_purge:
@@ -310,7 +311,7 @@ class DatasetAssociationManager(
            break
        return job

    def stop_creating_job(self, dataset_assoc):
    def stop_creating_job(self, dataset_assoc, flush=False):
        """
        Stops an dataset_assoc's creating job if all the job's other outputs are deleted.
        """
@@ -330,6 +331,8 @@ class DatasetAssociationManager(
                    job.mark_deleted(track_jobs_in_database)
                    if not track_jobs_in_database:
                        self.app.job_manager.stop(job)
                    if flush:
                        self.session().flush()
                    return True
        return False

+1 −2
Original line number Diff line number Diff line
@@ -876,8 +876,7 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
            hda.mark_deleted()
            hda.clear_associated_files()
            trans.log_event(f"Dataset id {str(id)} marked as deleted")
            self.hda_manager.stop_creating_job(hda)
            trans.sa_session.flush()
            self.hda_manager.stop_creating_job(hda, flush=True)
        except Exception:
            msg = f"HDA deletion failed (encoded: {dataset_id}, decoded: {id})"
            log.exception(msg)
+4 −2
Original line number Diff line number Diff line
@@ -1097,10 +1097,12 @@ class HistoriesContentsService(ServiceBase, ServesExportStores, ConsumesModelSto
        return hdas

    def __deserialize_dataset(self, trans, hda, payload: Dict[str, Any]):
        self.hda_deserializer.deserialize(hda, payload, user=trans.user, trans=trans)
        # TODO: when used in batch it would be a lot faster if we set flush=false
        # and the caller flushes only at the end or when a given chunk size is reached.
        self.hda_deserializer.deserialize(hda, payload, user=trans.user, trans=trans, flush=True)
        # TODO: this should be an effect of deleting the hda
        if payload.get("deleted", False):
            self.hda_manager.stop_creating_job(hda)
            self.hda_manager.stop_creating_job(hda, flush=True)

    def __index_legacy(
        self,
+25 −26
Original line number Diff line number Diff line
@@ -301,12 +301,7 @@ class DatasetsApiTestCase(ApiTestCase):

    @skip_without_tool("cat_data_and_sleep")
    def test_delete_cancels_job(self):
        with self.dataset_populator.test_history() as history_id:
            hda_id = self.dataset_populator.new_dataset(history_id)["id"]
            self.dataset_populator.wait_for_history_jobs(history_id)
            active_jobs = self.dataset_populator.active_history_jobs(history_id)
            assert not active_jobs

        hda_id = self.dataset_populator.new_dataset(self.history_id)["id"]
        inputs = {
            "input1": {"src": "hda", "id": hda_id},
            "sleep_time": 10,
@@ -314,19 +309,23 @@ class DatasetsApiTestCase(ApiTestCase):
        run_response = self.dataset_populator.run_tool_raw(
            "cat_data_and_sleep",
            inputs,
                history_id,
            self.history_id,
        ).json()
            queued_id = run_response["outputs"][0]["id"]
            active_jobs = self.dataset_populator.active_history_jobs(history_id)
            assert active_jobs
        output_hda_id = run_response["outputs"][0]["id"]
        job_id = run_response["jobs"][0]["id"]

        job_details = self.dataset_populator.get_job_details(job_id).json()
        assert job_details["state"] in ("new", "queued", "running"), job_details

        # Use stop_job to cancel the creating job
            delete_response = self.dataset_populator.delete_dataset(history_id, queued_id, stop_job=True)
        delete_response = self.dataset_populator.delete_dataset(self.history_id, output_hda_id, stop_job=True)
        self._assert_status_code_is_ok(delete_response)
        deleted_hda = delete_response.json()
        assert deleted_hda["deleted"], deleted_hda

        # The job should be cancelled
            active_jobs = self.dataset_populator.active_history_jobs(history_id)
            assert not active_jobs, "Job was not cancelled"
        deleted_job_details = self.dataset_populator.get_job_details(job_id).json()
        assert deleted_job_details["state"] in ("deleting", "deleted"), deleted_job_details

    def test_delete_batch(self):
        num_datasets = 4