Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Have a timeout for async/await function

Is there a way to attach a timeout to stop an async function if it takes too long?

Here's a simplified version of my code:

func search() async -> ResultEnum {
  // Call multiple Apis one after the other
}

Task.init {
  let searchResult = await search() 
  switch searchResult {
    // Handle all result scenarios
  }
}

I would like to have a deadline for the search() async function to provide a result, otherwise it should terminate and return ResultEnum.timeout.

like image 218
Wassim Avatar asked May 10 '26 06:05

Wassim


1 Answers

Thank you Rob for your comments, and for the link you provided.

I had to make some changes though, For some reason the initial task fetchTask kept going even after cancellation, until I added Task.checkCancellation() to it.

Here's what the code looks like now, if anyone is facing a similar issue:

func search() async throws -> ResultEnum {
  // This is the existing method as per my initial question.
  // It calls multiple Apis one after the other, then returns a result.
}

// Added the below method to introduce a deadline for search()
func search(withTimeoutSecs: Int) async {
    let fetchTask = Task {
        let taskResult = try await search()
        try Task.checkCancellation()
        // without the above line, search() kept going until server responded long after deadline.
        return taskResult
    }
        
    let timeoutTask = Task {
        try await Task.sleep(nanoseconds: UInt64(withTimeoutSecs) * NSEC_PER_SEC)
        fetchTask.cancel()
    }
        
    do {
        let result = try await fetchTask.value
        timeoutTask.cancel()
        return result
    } catch {
        return ResultEnum.failed(NetworkError.timeout)
    }
}

// Call site: Using the function (withTimeout:) instead of ()
Task.init {
    let searchResult = await search(withTimeoutSecs: 6) 
    switch searchResult {
      // Handle all result scenarios
    }
}
like image 88
Wassim Avatar answered May 12 '26 11:05

Wassim