CloudTranscriptionProvider.recordAndTranscribe() is blocking — needs async refactor and service integration #1

Closed
opened 2026-05-12 16:50:11 +00:00 by Mark · 1 comment
Owner

Problem

CloudTranscriptionProvider.recordAndTranscribe() uses Thread.sleep() for chunk timing and OkHttp.newCall(request).execute() (blocking) for HTTP requests. It is designed to be called from a coroutine loop, but:

  1. Thread.sleep() blocks the calling thread — should use delay() in a suspend function
  2. OkHttp.execute() blocks — should use enqueue() or kotlinx.coroutines with withContext(Dispatchers.IO)
  3. TranscriptionService.kt doesn't use the TranscriptionProvider abstraction at all — it still hardcodes android.speech.SpeechRecognizer directly. The cloud backend is never actually activated in the service loop, so this entire path is dead code in production.

Location

  • app/src/main/java/com/voicetranscriber/service/CloudTranscriptionProvider.kt (lines 75–80, 102, 150)
  • app/src/main/java/com/voicetranscriber/service/TranscriptionService.kt (lines 93–167)

Suggested approach

  1. Make recordAndTranscribe() a suspend function, replace Thread.sleep() with kotlinx.coroutines.delay(), and use withContext(Dispatchers.IO) for the blocking HTTP call
  2. Refactor TranscriptionService.kt to use SpeechBackend.select() to pick a backend at startup, then run the appropriate continuous loop:
    • For ANDROID/FIREOS: existing SpeechRecognizer callback pattern
    • For CLOUD: coroutine loop calling recordAndTranscribe() and feeding results through the listener
  3. Store and read BackendConfig from SharedPreferences at service startup
  4. Consider suspendCancellableCoroutine for the OkHttp call if keeping the current HTTP client

Part of closing the gap between the provider abstraction layer and the actual service implementation.

## Problem `CloudTranscriptionProvider.recordAndTranscribe()` uses `Thread.sleep()` for chunk timing and `OkHttp.newCall(request).execute()` (blocking) for HTTP requests. It is designed to be called from a coroutine loop, but: 1. `Thread.sleep()` blocks the calling thread — should use `delay()` in a `suspend` function 2. `OkHttp.execute()` blocks — should use `enqueue()` or `kotlinx.coroutines` with `withContext(Dispatchers.IO)` 3. **`TranscriptionService.kt` doesn't use the `TranscriptionProvider` abstraction at all** — it still hardcodes `android.speech.SpeechRecognizer` directly. The cloud backend is never actually activated in the service loop, so this entire path is dead code in production. ## Location - `app/src/main/java/com/voicetranscriber/service/CloudTranscriptionProvider.kt` (lines 75–80, 102, 150) - `app/src/main/java/com/voicetranscriber/service/TranscriptionService.kt` (lines 93–167) ## Suggested approach 1. Make `recordAndTranscribe()` a `suspend` function, replace `Thread.sleep()` with `kotlinx.coroutines.delay()`, and use `withContext(Dispatchers.IO)` for the blocking HTTP call 2. Refactor `TranscriptionService.kt` to use `SpeechBackend.select()` to pick a backend at startup, then run the appropriate continuous loop: - For `ANDROID`/`FIREOS`: existing `SpeechRecognizer` callback pattern - For `CLOUD`: coroutine loop calling `recordAndTranscribe()` and feeding results through the listener 3. Store and read `BackendConfig` from SharedPreferences at service startup 4. Consider `suspendCancellableCoroutine` for the OkHttp call if keeping the current HTTP client Part of closing the gap between the provider abstraction layer and the actual service implementation.
Author
Owner

Fixed in commit. Closing.

Fixed in commit. Closing.
Mark closed this issue 2026-05-13 16:43:04 +00:00
Sign in to join this conversation.
No description provided.