def cancel_job(self: Job, pipeline: Pipeline | None = None, enqueue_dependents: bool = False):
    """Cancels the given job, which will prevent the job from ever being
    ran (or inspected).

    This method merely exists as a high-level API call to cancel jobs
    without worrying about the internals required to implement job
    cancellation.

    You can enqueue the jobs dependents optionally,
    Same pipelining behavior as Queue.enqueue_dependents on whether or not a pipeline is passed in.

    Args:
        pipeline (Optional[Pipeline], optional): The Redis' pipeline to use. Defaults to None.
        enqueue_dependents (bool, optional): Whether to enqueue dependents jobs. Defaults to False.

    Raises:
        InvalidJobOperation: If the job has already been cancelled.
    """
    if self.is_canceled:
        raise InvalidJobOperation("Cannot cancel already canceled job: {}".format(self.get_id()))

    pipe = pipeline or self.connection.pipeline()

    while True:
        try:
            q = Queue(
                name=self.origin,
                connection=self.connection,
                job_class=self.__class__,
                serializer=self.serializer,
            )

            self.set_status(JobStatus.CANCELED, pipeline=pipe)
            if enqueue_dependents:
                # Only WATCH if no pipeline passed, otherwise caller is responsible
                if pipeline is None:
                    pipe.watch(self.dependents_key)
                q.enqueue_dependents(self, pipeline=pipeline, exclude_job_id=self.id)

            # ---block with custom changes---
            # go through all dependencies and remove the current job from dependency's dependents_key
            for dependency in self.fetch_dependencies(pipeline=pipe):
                pipe.srem(dependency.dependents_key, self.id)
            # ---block with custom changes---

            self._remove_from_registries(pipeline=pipe, remove_from_queue=True)

            registry = rq.registry.CanceledJobRegistry(
                self.origin, self.connection, job_class=self.__class__, serializer=self.serializer
            )
            registry.add(self, pipeline=pipe)
            if pipeline is None:
                pipe.execute()
            break
        except WatchError:
            if pipeline is None:
                continue
            else:
                # if the pipeline comes from the caller, we re-raise the
                # exception as it is the responsibility of the caller to
                # handle it
                raise
Cancels the given job, which will prevent the job from ever being
    ran (or inspected).

    This method merely exists as a high-level API call to cancel jobs
    without worrying about the internals required to implement job
    cancellation.

    You can enqueue the jobs dependents optionally,
    Same pipelining behavior as Queue.enqueue_dependents on whether or not a pipeline is passed in.

    Args:
        pipeline (Optional[Pipeline], optional): The Redis' pipeline to use. Defaults to None.
        enqueue_dependents (bool, optional): Whether to enqueue dependents jobs. Defaults to False.

    Raises:
        InvalidJobOperation: If the job has already been cancelled.
    
cvat/rq_patching.py