Spawns a thread that calls ``compute fn`` (along with additional arguments
        ``*compute_args`` and ``**compute_kwargs``), then applies the returned value to
        :meth:`.Bot.answerInlineQuery` to answer the inline query.
        If a preceding thread is already working for a user, that thread is cancelled,
        thus ensuring at most one active thread per user id.

        :param inline_query:
            The inline query to be processed. The originating user is inferred from ``msg['from']['id']``.

        :param compute_fn:
            A **thread-safe** function whose returned value is given to :meth:`.Bot.answerInlineQuery` to send.
            May return:

            - a *list* of `InlineQueryResult <https://core.telegram.org/bots/api#inlinequeryresult>`_
            - a *tuple* whose first element is a list of `InlineQueryResult <https://core.telegram.org/bots/api#inlinequeryresult>`_,
              followed by positional arguments to be supplied to :meth:`.Bot.answerInlineQuery`
            - a *dictionary* representing keyword arguments to be supplied to :meth:`.Bot.answerInlineQuery`

        :param \*compute_args: positional arguments to ``compute_fn``
        :param \*\*compute_kwargs: keyword arguments to ``compute_fn``

def answer(outerself, inline_query, compute_fn, *compute_args, **compute_kwargs):
        """
        Spawns a thread that calls ``compute fn`` (along with additional arguments
        ``*compute_args`` and ``**compute_kwargs``), then applies the returned value to
        :meth:`.Bot.answerInlineQuery` to answer the inline query.
        If a preceding thread is already working for a user, that thread is cancelled,
        thus ensuring at most one active thread per user id.

        :param inline_query:
            The inline query to be processed. The originating user is inferred from ``msg['from']['id']``.

        :param compute_fn:
            A **thread-safe** function whose returned value is given to :meth:`.Bot.answerInlineQuery` to send.
            May return:

            - a *list* of `InlineQueryResult <https://core.telegram.org/bots/api#inlinequeryresult>`_
            - a *tuple* whose first element is a list of `InlineQueryResult <https://core.telegram.org/bots/api#inlinequeryresult>`_,
              followed by positional arguments to be supplied to :meth:`.Bot.answerInlineQuery`
            - a *dictionary* representing keyword arguments to be supplied to :meth:`.Bot.answerInlineQuery`

        :param \*compute_args: positional arguments to ``compute_fn``
        :param \*\*compute_kwargs: keyword arguments to ``compute_fn``
        """

        from_id = inline_query['from']['id']

        class Worker(threading.Thread):
            def __init__(innerself):
                super(Worker, innerself).__init__()
                innerself._cancelled = False

            def cancel(innerself):
                innerself._cancelled = True

            def run(innerself):
                try:
                    query_id = inline_query['id']

                    if innerself._cancelled:
                        return

                    # Important: compute function must be thread-safe.
                    ans = compute_fn(*compute_args, **compute_kwargs)

                    if innerself._cancelled:
                        return

                    if isinstance(ans, list):
                        outerself._bot.answerInlineQuery(query_id, ans)
                    elif isinstance(ans, tuple):
                        outerself._bot.answerInlineQuery(query_id, *ans)
                    elif isinstance(ans, dict):
                        outerself._bot.answerInlineQuery(query_id, **ans)
                    else:
                        raise ValueError('Invalid answer format')
                finally:
                    with outerself._lock:
                        # Delete only if I have NOT been cancelled.
                        if not innerself._cancelled:
                            del outerself._workers[from_id]

                        # If I have been cancelled, that position in `outerself._workers`
                        # no longer belongs to me. I should not delete that key.

        # Several threads may access `outerself._workers`. Use `outerself._lock` to protect.
        with outerself._lock:
            if from_id in outerself._workers:
                outerself._workers[from_id].cancel()

            outerself._workers[from_id] = Worker()
            outerself._workers[from_id].start()