```python:inference/usage_tracking/collector.py
import asyncio
import atexit
import time
from collections import defaultdict
from queue import Queue
from threading import Event, Lock, Thread
from typing import Any, DefaultDict, Dict, Tuple, TypeVar
from uuid import uuid4

from inference.core.env import GCP_SERVERLESS, LAMBDA, REDIS_HOST
from inference.core.logger import logger
from inference.usage_tracking.config import (TelemetrySettings,
                                             get_telemetry_settings)
from inference.usage_tracking.payload_helpers import (APIKey, APIKeyHash,
                                                      APIKeyUsage,
                                                      ResourceCategory,
                                                      ResourceID, UsagePayload)
from inference.usage_tracking.plan_details import PlanDetails
from inference.usage_tracking.redis_queue import RedisQueue
from inference.usage_tracking.sqlite_queue import SQLiteQueue
from typing_extensions import ParamSpec

try:
    from inference_sdk.config import apply_duration_minimum
except ImportError:
    apply_duration_minimum = None

T = TypeVar("T")
P = ParamSpec("P")


class UsageCollector:

    _lock = Lock()

    def __init__(self):
        with UsageCollector._lock:
            if self._queue:
                return

        # Async lock only for async protection, should not be shared between threads
        self._async_lock = None
        try:
            self._async_lock = asyncio.Lock()
        except Exception as exc:
            logger.debug("Failed to create async lock %s", exc)

        self._exec_session_id = f"{time.time_ns()}_{uuid4().hex[:4]}"

        self._settings: TelemetrySettings = get_telemetry_settings()
        self._usage: APIKeyUsage = self.empty_usage_dict(
            exec_session_id=self._exec_session_id
        )

        self._hashed_api_keys: Dict[APIKey, APIKeyHash] = {}
        self._api_keys_hashing_enabled = True

        self._plan_details = PlanDetails(
            api_plan_endpoint_url=self._settings.api_plan_endpoint_url,
            webrtc_plans_endpoint_url=self._settings.webrtc_plans_endpoint_url,
            sqlite_cache_enabled=False,
            api_plan_cache_ttl_seconds=self._settings.api_plan_cache_ttl_seconds,
        )
        if (LAMBDA or GCP_SERVERLESS) and REDIS_HOST:
            logger.debug("Persistence through RedisQueue")
            self._queue: "Queue[UsagePayload]" = RedisQueue()
            self._api_keys_hashing_enabled = False
        elif (LAMBDA or GCP_SERVERLESS) or not self._settings.use_persistent_queue:
            logger.debug("No persistence")
            self._queue: "Queue[UsagePayload]" = Queue(
                maxsize=self._settings.queue_size
            )
            self._api_keys_hashing_enabled = False
        else:
            try:
                self._queue = SQLiteQueue()
                logger.debug("Persistence through SQLiteQueue")
            except Exception as exc:
                logger.debug("Unable to create instance of SQLiteQueue, %s", exc)
                logger.debug("No persistence")
                self._queue: "Queue[UsagePayload]" = Queue(
                    maxsize=self._settings.queue_size
                )
                self._api_keys_hashing_enabled = False
            try:
                self._plan_details = PlanDetails(
                    api_plan_endpoint_url=self._settings.api_plan_endpoint_url,
                    webrtc_plans_endpoint_url=self._settings.webrtc_plans_endpoint_url,
                    api_plan_cache_ttl_seconds=self._settings.api_plan_cache_ttl_seconds,
                )
                logger.debug("Cached plan details")
            except Exception as exc:
                logger.debug("Unable to create instance of SQLiteQueue, %s", exc)
        self._queue_lock = Lock()

        self._system_info_lock = Lock()
        self._system_info: Dict[str, Any] = {}
        self._resource_details_lock = Lock()
        self._resource_details: DefaultDict[
            APIKey, Dict[Tuple[ResourceCategory, ResourceID], Dict[str, Any]]
        ] = defaultdict(dict)

        self._terminate_collector_thread = Event()
        self._collector_thread = Thread(target=self._usage_collector, daemon=True)
        self._collector_thread.start()

        self._terminate_sender_thread = Event()
        self._sender_thread = Thread(target=self._usage_sender, daemon=True)
        self._sender_thread.start()

        atexit.register(self._cleanup)

    @staticmethod
    def _compute_execution_duration(t1: float, t2: float) -> float:
        raw = t2 - t1
        if not GCP_SERVERLESS:
            return raw

        # Localize globals to reduce attribute lookups on hot path
        adm = apply_duration_minimum
        MIN_DUR = 0.1
        if adm is not None:
            try:
                # Only catch LookupError exactly as original code did
                if adm.get():
                    return raw if raw >= MIN_DUR else MIN_DUR
                return raw
            except LookupError:
                pass

        # Default when apply_duration_minimum is None or LookupError occurred
        return raw if raw >= MIN_DUR else MIN_DUR
```