import threading

from typing import Optional

# Holds the request id for the current execution. Thread-local so that a value
# set by one execution cannot bleed into another running concurrently.
_state = threading.local()


def set_request_id(request_id):
    # type: (Optional[str]) -> None
    """
    Store the request id for the current execution. Callers running inside an
    AWS Lambda should set this to ``context.aws_request_id`` at the start of the
    handler so that processors reuse it as their unique id.
    :param request_id: the request id to associate with the current execution
    """
    _state.request_id = request_id


def get_request_id():
    # type: () -> Optional[str]
    """
    Return the request id stored for the current execution, or None if none has
    been set.
    :return: the current request id or None
    """
    return getattr(_state, "request_id", None)


def clear():
    # type: () -> None
    """
    Remove the request id stored for the current execution. Should be called in
    a ``finally`` block at the end of each invocation so a stale id is never
    reused by a later one (e.g. on a reused Lambda execution environment).
    """
    _state.request_id = None
