def METHOD_NAME(self) -> None:
    """Check for services that need to be rebuilt.
    These will have their `dirty` attribute set, which is used to create tasks.
    """
    idx = Taskcluster.get_service("index")
    queue = Taskcluster.get_service("queue")
    # for each service, check taskcluster index
    #   any service that would expire before next run, should be rebuilt
    assert self.now is not None
    next_run = self.now + CRON_PERIOD
    for svc in self.services.values():
        if svc.dirty:
            continue
        index_path = f"project.fuzzing.orion.{svc.name}.{self.main_branch}"
        rebuild = False
        try:
            result = idx.findTask(index_path)
        except TaskclusterRestFailure:
            LOG.warning(
                "%s %s is dirty because %s does not exist",
                type(svc).__name__,
                svc.name,
                index_path,
            )
            rebuild = True
        else:
            result = queue.task(result["taskId"])
            if (
                min(
                    isoparse(result["deadline"]) + ARTIFACTS_EXPIRE,
                    isoparse(result["expires"]),
                )
                < next_run
            ):
                LOG.warning(
                    "%s %s is dirty because %s expires %s",
                    type(svc).__name__,
                    svc.name,
                    index_path,
                    result["expires"],
                )
                rebuild = True
        if rebuild:
            svc.dirty = True
            # propagate dirty bit every time to minimize checking the index
            self.services.propagate_dirty([svc])