Hieu Truong
06/26/2024, 8:04 AM<http://Dispatchers.IO|Dispatchers.IO>
at different coroutine, I tried to fetch information with different endpoint, showing that It wait until the download progress is completed before handling it.
Is that normal? How can I make it work async?
Here is my manifest:
override fun getUpdateManifest(url: String, callback: (Either<UpdateModel>) -> Unit) {
suspend fun internalGetManifest() {
try {
val response = updateApi.getManifest(url).toDomain() // << it waits here until download is completed.
callback(Either.Success(response))
} catch (e: Exception) {
callback(Either.Error(message = e.localizedMessage ?: "Unknown error", cause = e))
}
}
CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>).launch {
internalGetManifest()
}
}
Here is my download using WorkManager:
override suspend fun doWork(): Result = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
val url = inputData.getString(PARAM_URL) ?: return@withContext Result.failure()
val destinationFile = UpdateManager.destinationFile
var downloadResult: Result = Result.failure()
try {
updateRepository.downloadUpdate(url = url, destination = destinationFile)
.onStart { setProgress(workDataOf(PROGRESS_ARG to 0f)) }
.onCompletion { downloadResult = Result.success() }
.collect { setProgress(workDataOf(PROGRESS_ARG to it)) }
} catch (e: Exception) {
downloadResult = Result.failure()
e.printStackTrace()
}
return@withContext downloadResult
}
And my Ktor client:
val ktorHttpClient = HttpClient(Android) {
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
engine {
connectTimeout = TIME_OUT
socketTimeout = TIME_OUT
}
}
install(Logging) {
logger = object : Logger {
override fun log(message: String) {
Log.v("Logger Ktor =>", message)
}
}
level = LogLevel.ALL
}
install(ResponseObserver) {
onResponse {
Log.d("HTTP status:", "${it.status.value}")
}
}
install(DefaultRequest) {
headers.append(ContentType, io.ktor.http.ContentType.Application.Json.toString())
}
}
Aleksei Tirman [JB]
06/26/2024, 9:10 AMHieu Truong
06/26/2024, 11:15 AMinterface UpdateRetrofitService {
@GET
suspend fun getManifest(@Url url: String): UpdateDto
}
override fun getUpdateManifest(url: String, callback: (Either<UpdateModel>) -> Unit) {
suspend fun internalGetManifest() {
try {
val response = retrofitService.getManifest(url).toDomain()
callback(Either.Success(response))
} catch (e: Exception) {
callback(Either.Error(message = e.localizedMessage ?: "Unknown error", cause = e))
}
}
CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>).launch {
internalGetManifest()
}
}
Aleksei Tirman [JB]
06/26/2024, 1:59 PMfun main(): Unit = runBlocking {
val client = HttpClient(CIO)
val deferred1 = async {
client.get("<https://httpbin.org/get>").bodyAsText()
}
val deferred2 = async {
client.get("<https://httpbin.org/get>").bodyAsText()
}
val responses = listOf(deferred1, deferred2).awaitAll()
println(responses)
}