vc=58: parallel SponsorBlock + RYD fetch on video open
Sequential withContext blocks left the slower of the two requests
fully serialized behind the faster one — 200-500ms wasted per video
open. async{}+await in a coroutineScope runs both on Dispatchers.IO
concurrently. Saves the slower-task latency on every detail-screen
load.
Rust port was overscoped — the dominant cost is network latency,
not parse, so a UniFFI hop wouldn't help and the parallelization
fix is a 5-line Kotlin change. Updated the Rust port plan memo
accordingly.
This commit is contained in:
parent
8dec2f2621
commit
7fff36c5e3
2 changed files with 21 additions and 8 deletions
|
|
@ -55,6 +55,6 @@ const val NEWPIPE_APPLICATION_ID_NEW = "net.newpipe.app"
|
|||
// vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via
|
||||
// strawcore-core (Sulkta-Coop/strawcore) via the UniFFI wrapper; no
|
||||
// NewPipeExtractor in the runtime path.
|
||||
const val STRAW_VERSION_CODE = 57
|
||||
const val STRAW_VERSION_NAME = "0.1.0-BQ"
|
||||
const val STRAW_VERSION_CODE = 58
|
||||
const val STRAW_VERSION_NAME = "0.1.0-BR"
|
||||
const val STRAW_APPLICATION_ID = "com.sulkta.straw"
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import com.sulkta.straw.util.runCatchingCancellable
|
|||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
|
@ -160,13 +162,24 @@ class VideoDetailViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
val ryd = withContext(Dispatchers.IO) {
|
||||
runCatchingCancellable { RydClient.fetch(videoId) }.getOrNull()
|
||||
}
|
||||
// RYD + SponsorBlock in parallel — both are independent
|
||||
// network round-trips that block the detail UI. Running
|
||||
// them sequentially via two withContext blocks left the
|
||||
// slower one fully serialized behind the faster one
|
||||
// (~200-500ms wasted per video open). async{}.await()
|
||||
// on Dispatchers.IO closes that gap.
|
||||
val sbCats = Settings.get().sbCategories.value.map { it.key }
|
||||
val segments = if (sbCats.isEmpty()) emptyList() else withContext(Dispatchers.IO) {
|
||||
runCatchingCancellable { SponsorBlockClient.fetch(videoId, sbCats) }
|
||||
.getOrDefault(emptyList())
|
||||
val (ryd, segments) = coroutineScope {
|
||||
val rydDeferred = async(Dispatchers.IO) {
|
||||
runCatchingCancellable { RydClient.fetch(videoId) }.getOrNull()
|
||||
}
|
||||
val sbDeferred = async(Dispatchers.IO) {
|
||||
if (sbCats.isEmpty()) emptyList()
|
||||
else runCatchingCancellable {
|
||||
SponsorBlockClient.fetch(videoId, sbCats)
|
||||
}.getOrDefault(emptyList())
|
||||
}
|
||||
rydDeferred.await() to sbDeferred.await()
|
||||
}
|
||||
|
||||
val related = info.related.map { r ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue