Skip to content

Commit

Permalink
optimal
Browse files Browse the repository at this point in the history
  • Loading branch information
hoanganhtuan95ptit committed Jan 26, 2023
1 parent ccbbe9c commit 2bf7a14
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 27 deletions.
Binary file modified .gradle/7.2/executionHistory/executionHistory.bin
Binary file not shown.
Binary file modified .gradle/7.2/executionHistory/executionHistory.lock
Binary file not shown.
Binary file modified .gradle/7.2/fileHashes/fileHashes.bin
Binary file not shown.
Binary file modified .gradle/7.2/fileHashes/fileHashes.lock
Binary file not shown.
Binary file modified .gradle/7.2/fileHashes/resourceHashesCache.bin
Binary file not shown.
Binary file modified .gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
26 changes: 26 additions & 0 deletions core-app/src/main/java/com/one/coreapp/utils/Lock.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.one.coreapp.utils

import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

object Lock {

private val mutex = Mutex()

private val ownerAndMutex = hashMapOf<Any, Mutex>()

suspend fun <T> withLock(owner: Any = this, action: suspend () -> T): T {

var mutex: Mutex

this.mutex.withLock {

mutex = ownerAndMutex.get(owner) ?: Mutex().also { mu -> ownerAndMutex[owner] = mu }
}

return mutex.withLock {

action.invoke()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private val handler = CoroutineExceptionHandler { _: CoroutineContext, throwable

fun log(name: String, data: String = "") = GlobalScope.launch(handler + Dispatchers.IO) {

val eventName = name.normalize().replace(".", "").replace("-", "_")
val eventName = name.normalize().replace(".", "").replace(" ", "_").replace("-", "_")

App.shared.logAnalytics.map { it.execute(Analytics.Param(eventName, data)) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.google.mlkit.nl.translate.Translator
import com.google.mlkit.nl.translate.TranslatorOptions
import com.one.coreapp.data.usecase.ResultState
import com.one.coreapp.data.usecase.isFailed
import com.one.coreapp.utils.Lock
import com.one.coreapp.utils.extentions.log
import com.one.coreapp.utils.extentions.logException
import com.one.coreapp.utils.extentions.resumeActive
Expand All @@ -26,53 +27,56 @@ class MlkitTranslateTask : TranslateTask {

override suspend fun execute(param: TranslateTask.Param): ResultState<List<String>> = withContext(coroutineContext) {

val sourceLanguage = map[param.inputCode] ?: param.inputCode
val inputCode = map[param.inputCode] ?: param.inputCode

val targetLanguage = map[param.outputCode] ?: param.outputCode
val outputCode = map[param.outputCode] ?: param.outputCode


if (sourceLanguage.lowercase() in listOf("", "wo") || targetLanguage.lowercase() in listOf("", "wo") || sourceLanguage == targetLanguage) {
val listBreak = listOf("", "wo", "und-latn")

return@withContext ResultState.Failed(java.lang.RuntimeException("not support sourceLanguage:$sourceLanguage targetLanguage:$targetLanguage"))
}

val options = TranslatorOptions.Builder()
.setSourceLanguage(sourceLanguage)
.setTargetLanguage(targetLanguage)
.build()
if (inputCode.lowercase() in listBreak || outputCode.lowercase() in listBreak || inputCode == outputCode) {

return@withContext ResultState.Failed(java.lang.RuntimeException("not support inputCode:$inputCode outputCode:$outputCode"))
}

val translator = Translation.getClient(options)
val downloadInputCodeStateDeferred = async {

Lock.withLock(inputCode) { downloadModelIfNeededTimeout(inputCode) }
}

val downloadState1Deferred = async {
val downloadOutputCodeStateDeferred = async {

downloadModelIfNeededTimeout(sourceLanguage)
Lock.withLock(outputCode) { downloadModelIfNeededTimeout(outputCode) }
}

val downloadState2Deferred = async {

downloadModelIfNeededTimeout(targetLanguage)
val downloadInputCodeState = downloadInputCodeStateDeferred.await()

if (downloadInputCodeState.isFailed()) {

return@withContext downloadInputCodeState
}


val downloadState1 = downloadState1Deferred.await()
val downloadOutputCodeState = downloadOutputCodeStateDeferred.await()

if (downloadState1.isFailed()) {
if (downloadOutputCodeState.isFailed()) {

return@withContext downloadState1
return@withContext downloadOutputCodeState
}


val downloadState2 = downloadState2Deferred.await()
val options = TranslatorOptions.Builder()
.setSourceLanguage(inputCode)
.setTargetLanguage(outputCode)
.build()

if (downloadState2.isFailed()) {

return@withContext downloadState2
}
val translator = Translation.getClient(options)


log("Mlkit Translate Task", "$sourceLanguage $targetLanguage")
log("Mlkit Translate Task", "$inputCode $outputCode")

val translateStateList = param.text.map {

Expand Down Expand Up @@ -101,7 +105,11 @@ class MlkitTranslateTask : TranslateTask {

private suspend fun downloadModelIfNeededTimeout(languageCode: String) = kotlin.runCatching {

withTimeout(2 * 60 * 1000) {
if (isModelDownloaded(languageCode)) {

return@runCatching ResultState.Success(emptyList())
} else withTimeout(2 * 60 * 1000) {

downloadModelIfNeeded(languageCode)
}
}.getOrElse {
Expand All @@ -111,17 +119,34 @@ class MlkitTranslateTask : TranslateTask {

private suspend fun downloadModelIfNeeded(languageCode: String) = suspendCancellableCoroutine<ResultState<List<String>>> { continuation ->

modelManager.download(TranslateRemoteModel.Builder(languageCode).build(), downloadConditions).addOnSuccessListener {
val remoteModel = TranslateRemoteModel.Builder(languageCode).build()

modelManager.download(remoteModel, downloadConditions).addOnSuccessListener {

continuation.resumeActive(ResultState.Success(emptyList()))
}.addOnFailureListener {

logException(RuntimeException("Mlkit Translate Task download Model If Needed", it))
logException(RuntimeException("Mlkit Translate Task download Model If Needed $languageCode", it))

continuation.resumeActive(ResultState.Failed(it))
}
}

private suspend fun isModelDownloaded(languageCode: String) = suspendCancellableCoroutine<Boolean> { continuation ->

val remoteModel = TranslateRemoteModel.Builder(languageCode).build()

modelManager.isModelDownloaded(remoteModel).addOnSuccessListener {

continuation.resumeActive(it)
}.addOnFailureListener {

logException(RuntimeException("IS MODEL DOWNLOADED $languageCode", it))

continuation.resumeActive(false)
}
}

private suspend fun translate(translator: Translator, text: String): ResultState<String> = suspendCancellableCoroutine { continuation ->

translator.translate(text).addOnSuccessListener { translatedText ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class EnSpellingTask : SpellingTask {
val audio = it.getElementsByTag("source").firstOrNull()?.attr("src")?.takeIf { url -> url.isNotBlank() }
?: it.getElementsByClass("mw-tmh-play").firstOrNull()?.attr("href")?.takeIf { url -> url.isNotBlank() }

Log.d("tuanha", "handleFromWiki: $text $audio")

val spelling = it.getElementsByClass("IPA").firstOrNull()

Expand Down

0 comments on commit 2bf7a14

Please sign in to comment.