Add timeout and retry logic to GroqTranscriptionService
This commit is contained in:
parent
6ea41020a0
commit
6ab3705123
@ -3,8 +3,15 @@ import os
|
||||
|
||||
class GroqTranscriptionService {
|
||||
private let logger = Logger(subsystem: "com.prakashjoshipax.voiceink", category: "GroqService")
|
||||
|
||||
private let baseTimeout: TimeInterval = 120
|
||||
private let maxRetries: Int = 2
|
||||
private let initialRetryDelay: TimeInterval = 1.0
|
||||
|
||||
func transcribe(audioURL: URL, model: any TranscriptionModel) async throws -> String {
|
||||
return try await transcribeWithRetry(audioURL: audioURL, model: model)
|
||||
}
|
||||
|
||||
private func makeTranscriptionRequest(audioURL: URL, model: any TranscriptionModel) async throws -> String {
|
||||
let config = try getAPIConfig(for: model)
|
||||
|
||||
let boundary = "Boundary-\(UUID().uuidString)"
|
||||
@ -12,6 +19,7 @@ class GroqTranscriptionService {
|
||||
request.httpMethod = "POST"
|
||||
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
|
||||
request.setValue("Bearer \(config.apiKey)", forHTTPHeaderField: "Authorization")
|
||||
request.timeoutInterval = baseTimeout
|
||||
|
||||
let body = try createOpenAICompatibleRequestBody(audioURL: audioURL, modelName: config.modelName, boundary: boundary)
|
||||
|
||||
@ -34,7 +42,65 @@ class GroqTranscriptionService {
|
||||
throw CloudTranscriptionError.noTranscriptionReturned
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func transcribeWithRetry(audioURL: URL, model: any TranscriptionModel) async throws -> String {
|
||||
var retries = 0
|
||||
var currentDelay = initialRetryDelay
|
||||
|
||||
while retries < self.maxRetries {
|
||||
do {
|
||||
return try await makeTranscriptionRequest(audioURL: audioURL, model: model)
|
||||
} catch let error as CloudTranscriptionError {
|
||||
switch error {
|
||||
case .networkError:
|
||||
retries += 1
|
||||
if retries < self.maxRetries {
|
||||
logger.warning("Transcription request failed, retrying in \(currentDelay)s... (Attempt \(retries)/\(self.maxRetries))")
|
||||
try await Task.sleep(nanoseconds: UInt64(currentDelay * 1_000_000_000))
|
||||
currentDelay *= 2
|
||||
} else {
|
||||
logger.error("Transcription request failed after \(self.maxRetries) retries.")
|
||||
throw error
|
||||
}
|
||||
case .apiRequestFailed(let statusCode, _):
|
||||
if (500...599).contains(statusCode) || statusCode == 429 {
|
||||
retries += 1
|
||||
if retries < self.maxRetries {
|
||||
logger.warning("Transcription request failed with status \(statusCode), retrying in \(currentDelay)s... (Attempt \(retries)/\(self.maxRetries))")
|
||||
try await Task.sleep(nanoseconds: UInt64(currentDelay * 1_000_000_000))
|
||||
currentDelay *= 2
|
||||
} else {
|
||||
logger.error("Transcription request failed after \(self.maxRetries) retries.")
|
||||
throw error
|
||||
}
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
default:
|
||||
throw error
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
if nsError.domain == NSURLErrorDomain &&
|
||||
[NSURLErrorNotConnectedToInternet, NSURLErrorTimedOut, NSURLErrorNetworkConnectionLost].contains(nsError.code) {
|
||||
retries += 1
|
||||
if retries < self.maxRetries {
|
||||
logger.warning("Transcription request failed with network error, retrying in \(currentDelay)s... (Attempt \(retries)/\(self.maxRetries))")
|
||||
try await Task.sleep(nanoseconds: UInt64(currentDelay * 1_000_000_000))
|
||||
currentDelay *= 2
|
||||
} else {
|
||||
logger.error("Transcription request failed after \(self.maxRetries) retries with network error.")
|
||||
throw CloudTranscriptionError.networkError(error)
|
||||
}
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw CloudTranscriptionError.noTranscriptionReturned
|
||||
}
|
||||
|
||||
private func getAPIConfig(for model: any TranscriptionModel) throws -> APIConfig {
|
||||
guard let apiKey = UserDefaults.standard.string(forKey: "GROQAPIKey"), !apiKey.isEmpty else {
|
||||
throw CloudTranscriptionError.missingAPIKey
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user