code: def gc(older_than, backend_store_uri, run_ids, experiment_ids):
      """
      Permanently delete runs in the `deleted` lifecycle stage from the specified backend store.
      This command deletes all artifacts and metadata associated with the specified runs.
      If the provided artifact URL is invalid, the artifact deletion will be bypassed,
      and the gc process will continue.
      """
      from mlflow.utils.time import get_current_time_millis
  
      backend_store = _get_store(backend_store_uri, None)
      skip_experiments = False
      if not hasattr(backend_store, "_hard_delete_run"):
          raise MlflowException(
              "This cli can only be used with a backend that allows hard-deleting runs"
          )
  
      if not hasattr(backend_store, "_hard_delete_experiment"):
          warnings.warn(
              "The specified backend does not allow hard-deleting experiments. Experiments"
              " will be skipped.",
              FutureWarning,
              stacklevel=2,
          )
          skip_experiments = True
  
      time_delta = 0
  
      if older_than is not None:
          regex = re.compile(
              r"^((?P<days>[\.\d]+?)d)?((?P<hours>[\.\d]+?)h)?((?P<minutes>[\.\d]+?)m)"
              r"?((?P<seconds>[\.\d]+?)s)?$"
          )
          parts = regex.match(older_than)
          if parts is None:
              raise MlflowException(
                  f"Could not parse any time information from '{older_than}'. "
                  "Examples of valid strings: '8h', '2d8h5m20s', '2m4s'",
                  error_code=INVALID_PARAMETER_VALUE,
              )
          time_params = {
              name: float(param)
              for name, param in parts.groupdict().items()
              if param
          }
          time_delta = int(
              timedelta(**time_params).total_seconds() * 1000
          )
  
      deleted_run_ids_older_than = backend_store._get_deleted_runs(
          older_than=time_delta
      )
      run_ids = (
          run_ids.split(",") if run_ids else deleted_run_ids_older_than
      )
  
      time_threshold = get_current_time_millis() - time_delta
      if not skip_experiments:
          if experiment_ids:
              experiment_ids = experiment_ids.split(",")
              experiments = [
                  backend_store.get_experiment(id)
                  for id in experiment_ids
              ]
  
              # Ensure that the specified experiments are soft-deleted
              active_experiment_ids = [
                  e.experiment_id
                  for e in experiments
                  if e.lifecycle_stage != LifecycleStage.DELETED
              ]
              if active_experiment_ids:
                  raise MlflowException(
                      f"Experiments {active_experiment_ids} are not in the deleted lifecycle stage. "
                      "Only experiments in the deleted lifecycle stage can be hard-deleted.",
                      error_code=INVALID_PARAMETER_VALUE,
                  )
  
              # Ensure that the specified experiments are old enough
              if older_than:
                  non_old_experiment_ids = [
                      e.experiment_id
                      for e in experiments
                      if e.last_update_time is None
                      or e.last_update_time >= time_threshold
                  ]
                  if non_old_experiment_ids:
                      raise MlflowException(
                          f"Experiments {non_old_experiment_ids} are not older than the required"
                          f"age. Only experiments older than {older_than} can be deleted.",
                          error_code=INVALID_PARAMETER_VALUE,
                      )
          else:
              filter_string = (
                  f"last_update_time < {time_threshold}"
                  if older_than
                  else None
              )
  
              def fetch_experiments(token=None):
                  page = backend_store.search_experiments(
                      view_type=ViewType.DELETED_ONLY,
                      filter_string=filter_string,
                      page_token=token,
                  )
                  return (
                      (page + fetch_experiments(page.token))
                      if page.token
                      else page
                  )
  
              experiment_ids = [
                  exp.experiment_id for exp in fetch_experiments()
              ]
  
          def fetch_runs(token=None):
              page = backend_store.search_runs(
                  experiment_ids=experiment_ids,
                  filter_string="",
                  run_view_type=ViewType.DELETED_ONLY,
                  page_token=token,
              )
              return (
                  (page + fetch_runs(page.token))
                  if page.token
                  else page
              )
  
          run_ids.extend([run.info.run_id for run in fetch_runs()])
  
      for run_id in set(run_ids):
          run = backend_store.get_run(run_id)
          if run.info.lifecycle_stage != LifecycleStage.DELETED:
              raise MlflowException(
                  "Run % is not in `deleted` lifecycle stage. Only runs in"
                  " `deleted` lifecycle stage can be deleted." % run_id
              )
          # raise MlflowException if run_id is newer than older_than parameter
          if older_than and run_id not in deleted_run_ids_older_than:
              raise MlflowException(
                  f"Run {run_id} is not older than the required age. "
                  f"Only runs older than {older_than} can be deleted.",
                  error_code=INVALID_PARAMETER_VALUE,
              )
          # raise MlflowException if run_id is newer than older_than parameter
          if older_than and run_id not in deleted_run_ids_older_than:
              raise MlflowException(
                  f"Run {run_id} is not older than the required age. "
                  f"Only runs older than {older_than} can be deleted.",
                  error_code=INVALID_PARAMETER_VALUE,
              )
          artifact_repo = get_artifact_repository(run.info.artifact_uri)
          try:
              artifact_repo.delete_artifacts()
          except InvalidUrlException as iue:
              click.echo(
                  click.style(
                      f"An exception {iue!r} was raised during the deletion of a model artifact",
                      fg="yellow",
                  )
              )
              click.echo(
                  click.style(
                      f"Unable to resolve the provided artifact URL: '{artifact_repo}'. "
                      "The gc process will continue and bypass artifact deletion. "
                      "Please ensure that the artifact exists "
                      "and consider manually deleting any unused artifacts. ",
                      fg="yellow",
                  ),
              )
          backend_store._hard_delete_run(run_id)
          click.echo(
              f"Run with ID {run_id} has been permanently deleted."
          )
  
      if not skip_experiments:
          for experiment_id in experiment_ids:
              backend_store._hard_delete_experiment(experiment_id)
              click.echo(
                  f"Experiment with ID {experiment_id} has been permanently deleted."
              )
  
imports: import contextlib
  import importlib.metadata
  import json
  import logging
  import os
  import re
  import sys
  import warnings
  from datetime import timedelta
  import click
  from click import UsageError
  import mlflow.db
  import mlflow.deployments.cli
  import mlflow.experiments
  import mlflow.runs
  import mlflow.store.artifact.cli
  from mlflow import projects, version
  from mlflow.entities import ViewType
  from mlflow.entities.lifecycle_stage import LifecycleStage
  from mlflow.environment_variables import MLFLOW_EXPERIMENT_ID, MLFLOW_EXPERIMENT_NAME
  from mlflow.exceptions import InvalidUrlException, MlflowException
  from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE
  from mlflow.store.artifact.artifact_repository_registry import get_artifact_repository
  from mlflow.store.tracking import DEFAULT_ARTIFACTS_URI, DEFAULT_LOCAL_FILE_AND_ARTIFACT_PATH
  from mlflow.tracking import _get_store
  from mlflow.utils import cli_args
  from mlflow.utils.logging_utils import eprint
  from mlflow.utils.os import is_windows
  from mlflow.utils.process import ShellCommandException
  from mlflow.utils.server_cli_utils import artifacts_only_config_validation, resolve_default_artifact_root
label_desc: Use image node_id 7 for calling a global function with example usage: gc(older_than, backend_store_uri, run_ids, experiment_ids) and returns: unknown, unknown