We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Promise Time Limit

Number: 2749

Difficulty: Medium

Paid? No

Companies: N/A


Problem Description

Wrap an asynchronous function fn so that it either resolves with its result if it completes within t milliseconds or rejects with the string "Time Limit Exceeded" if it takes longer than t milliseconds to complete. The returned function should forward any arguments provided to fn.


Key Insights

  • Use a timeout mechanism (e.g. Promise.race in JavaScript) to compete between the asynchronous task and a timer.
  • The timer should reject after t milliseconds with the provided error message.
  • If fn throws or rejects before timeout, propagate that error immediately.
  • Make sure to forward arguments correctly to fn.

Space and Time Complexity

Time Complexity: O(1) per function call since the overhead is just starting an extra timer. Space Complexity: O(1) aside from the asynchronous call stack.


Solution

We create a wrapper function that returns a new function. When this new function is invoked, it simultaneously starts two asynchronous operations:

  1. The original function call with all its arguments.
  2. A timer that triggers a rejection after t milliseconds.

Using a race mechanism (such as Promise.race in JavaScript), whichever of these operations completes first determines the final outcome. Similar ideas are used in Python with asyncio.wait_for, in C++ with std::future and std::thread, and in Java with CompletableFuture and a scheduled executor. The main trick is to correctly cancel or ignore the other operation once one completes and to ensure proper propagation of errors.


Code Solutions

import asyncio

def timeLimit(fn, t):
    # Wrapper that returns a new async function
    async def wrapper(*args, **kwargs):
        try:
            # asyncio.wait_for will raise asyncio.TimeoutError if t milliseconds (converted to seconds) elapse
            return await asyncio.wait_for(fn(*args, **kwargs), timeout=t/1000)
        except asyncio.TimeoutError:
            # Raise exception with appropriate message
            raise Exception("Time Limit Exceeded")
    return wrapper

# Example usage:
# async def sample(n):
#     await asyncio.sleep(0.1)
#     return n * n
# limited = timeLimit(sample, 50)
← Back to All Questions