autodesk / coroutineworker Goto Github PK
View Code? Open in Web Editor NEWKotlin Coroutine-based workers for native
License: Apache License 2.0
Kotlin Coroutine-based workers for native
License: Apache License 2.0
🌮
We should replace [INSERT EMAIL ADDRESS]
with a contact email address.
When I trying to run this code:
GlobalScope.launch {
CoroutineWorker.withContext(Dispatchers.IO) {
while (true) {
delay(15)
}
}
}
approximately on 10-15th loop iteration iOS app crashes.
Kotlin: 1.4.31
coroutineworker: 0.6.2
Actual implementation of Dispatchers.IO:
actual val Dispatchers.IO: CoroutineDispatcher
get() = IODispatcher
When I wrote CoroutineWorker, the goal was always to help fill a gap in the ecosystem: multithreaded coroutine support for K/N, until Kotlin's coroutine library shipped stable support.
Stable support has been here for some time now, and this library has (as it was intended) moved into its "museum phase." Now that this library is no longer maintained and is no longer the right choice for modern multiplatform Kotlin, it's time to archive the GitHub repo
This needs a bump for the new version of Kotlin.
In case it helps, I get this error when trying to compile:
22:03 Incompatible Kotlin/Native libraries
There is a third-party library attached to the project that was compiled with an older Kotlin/Native compiler and can't be read in IDE: Gradle: com.autodesk:coroutineworker-iosx64:klib:0.3.1
Please edit Gradle buildfile(s) and specify library version compatible with Kotlin/Native 1.3.60. Then re-import the project in IDE.
I didn't clean before publishing, and it republished the old artifacts. If you try to use them on native, it'll say they're pre-1.4 artifacts.
It's was mentioned in several issues here that CoroutineWorker shouldn't be used with Coroutines-MT version. I'm not clear why? Coroutines-MT doesn't solve all issues on native target. The main problem is that it provides a single thread in Default dispatcher while CoroutineWorker has a thread pool. As well no IO dispatcher exists. So if we use Coroutines-MT we're effectively running all IO and computations on a single thread. Does it make sense?
I just watched the talk that @benasher44 gave at droidCon NYC about Concurrency in Kotlin/Native and decided to try this CoroutineWorker
library.
So what I am trying to do is consuming some backend REST API using Ktor inside CoroutineWorker.execute
. Basically, I am still not really sure if I am doing this correct but here is the code:
So I have a NetworkProvider
class:
internal class NetworkProvider<T : Endpoint>(private val engine: HttpClientEngine) {
private val client: HttpClient by lazy {
HttpClient(engine) {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
}
}
@UnstableDefault
internal suspend fun <R> request(endpoint: T, strategy: DeserializationStrategy<R>): R {
val response: String = client.request {
method = endpoint.method
url.apply {
protocol = URLProtocol.HTTPS
host = endpoint.baseUrl
val query = endpoint.parameters
.map { "${it.key}=${it.value}" }
.joinToString("&")
encodedPath = if (query.isNotEmpty()) {
"${endpoint.path}?$query"
} else {
endpoint.path
}
}
}
return Json.nonstrict.parse(strategy, response)
}
}
And then I use this NetworkProvider
inside my Repository class like this:
internal class MovieRepositoryImpl(
private val provider: NetworkProvider<MovieEndpoint>
) : MovieRepository {
override fun getMovieList(
year: Int,
page: Int,
sort: String,
completion: (Result<MovieListEntity>) -> Unit
) {
CoroutineWorker.execute {
val result = try {
val response = provider.request(
endpoint = MovieListEndpoint(year, page, sort),
strategy = MovieListEntity.serializer()
)
Result.Success(response)
} catch (error: Throwable) {
Result.Failure(error)
}
CoroutineWorker.withContext(MainDispatcher) {
completion(result)
}
}
}
}
But it's end up gave me this error messages:
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread
at 0 MovieCore 0x0000000109964fe7 kfun:kotlin.Throwable.<init>(kotlin.String?)kotlin.Throwable + 87
at 1 MovieCore 0x000000010995e355 kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 85
at 2 MovieCore 0x000000010995df15 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 85
at 3 MovieCore 0x0000000109990c95 kfun:kotlin.native.IncorrectDereferenceException.<init>(kotlin.String)kotlin.native.IncorrectDereferenceException + 85
at 4 MovieCore 0x00000001099add29 ThrowIncorrectDereferenceException + 137
at 5 MovieCore 0x0000000109cd3799 CheckIsMainThread + 25
at 6 MovieCore 0x0000000109c5a893 kfun:utils.<get-MainDispatcher>$core()kotlinx.coroutines.CoroutineDispatcher + 35
at 7 MovieCore 0x0000000109c3f7e4 kfun:repository.MovieRepositoryImpl.$getMovieList$lambda-1COROUTINE$1.invokeSuspend#internal + 1892
at 8 MovieCore 0x0000000109c40020 kfun:repository.MovieRepositoryImpl.$getMovieList$lambda-1COROUTINE$1.invoke#internal + 256
at 9 MovieCore 0x0000000109b069f3 kfun:kotlinx.coroutines.intrinsics.startUndispatchedOrReturn$kotlinx-coroutines-core@kotlinx.coroutines.internal.ScopeCoroutine<#GENERIC>.(#GENERIC;kotlin.coroutines.SuspendFunction1<#GENERIC,#GENERIC>)Generic + 899
at 10 MovieCore 0x0000000109ab11bd kfun:kotlinx.coroutines.coroutineScope(kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 429
at 11 MovieCore 0x0000000109c37f70 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-1COROUTINE$11.invokeSuspend#internal + 1520
at 12 MovieCore 0x0000000109c386a0 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-1COROUTINE$11.invoke#internal + 256
at 13 MovieCore 0x0000000109c33226 kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$processWorkItems$lambda-0COROUTINE$7.invokeSuspend#internal + 726
at 14 MovieCore 0x0000000109986618 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) + 712
at 15 MovieCore 0x0000000109afb06c kfun:kotlinx.coroutines.DispatchedTask.run() + 2732
at 16 MovieCore 0x0000000109ab606d kfun:kotlinx.coroutines.EventLoopImplBase.processNextEvent()ValueType + 813
at 17 MovieCore 0x0000000109b097c6 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 1958
at 18 MovieCore 0x0000000109b0886e kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 1246
at 19 MovieCore 0x0000000109b08de4 kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>;kotlin.Int)Generic + 372
at 20 MovieCore 0x0000000109c32da9 kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.enqueueWork$<anonymous>_3#internal + 217
at 21 MovieCore 0x0000000109c340fb kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$enqueueWork$<anonymous>_3$FUNCTION_REFERENCE$7.invoke#internal + 59
at 22 MovieCore 0x0000000109c3415b kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$enqueueWork$<anonymous>_3$FUNCTION_REFERENCE$7.$<bridge-UNN>invoke()#internal + 59
at 23 MovieCore 0x0000000109c3cca4 kfun:com.autodesk.coroutineworker.WorkerPool.performWork$lambda-1#internal + 308
at 24 MovieCore 0x0000000109c3d0df kfun:com.autodesk.coroutineworker.WorkerPool.$performWork$lambda-1$FUNCTION_REFERENCE$17.invoke#internal + 63
at 25 MovieCore 0x0000000109c3d13b kfun:com.autodesk.coroutineworker.WorkerPool.$performWork$lambda-1$FUNCTION_REFERENCE$17.$<bridge-UNN>invoke()#internal + 59
at 26 MovieCore 0x00000001099927c1 WorkerLaunchpad + 177
at 27 MovieCore 0x0000000109cd8069 _ZN6Worker19processQueueElementEb + 2569
at 28 MovieCore 0x0000000109cd8616 _ZN12_GLOBAL__N_113workerRoutineEPv + 54
at 29 libsystem_pthread.dylib 0x00007fff51c04d36 _pthread_start + 125
Anyone know how to work around this error message?
On my MacBook Pro with 10 cores I see that only 4 of them are used. I guess this is because the number of workers is not configurable and set to a fixed 4
. This should be configurable or at least use the number of CPU cores as a default.
We're trying to build a 32 bit version for our Kotlin Native Project and would love to support 32 bit. Is this possible right now?
There's no backwards compatibility in Kotlin/Native for now.
Hello guys! First of all, thanks for the lib! But I don't understand how to "go back" to the main thread when I get the result from the BG task, I have something like this:
interface Repository {
suspend fun getUser(): Either<Error, User>
}
And then, I want to use the worker like this:
CoroutineWorker.execute {
repository.getUser().fold(
error = { /* Update UI */ },
success = { /* Update UI */ }
)
}
I've tried with lot of approachs, like callbacks, or the withContext
but looks like no one of them works, any help??
Documentation makes references to examples. No examples are found in current version
i guess it's safe to ignore the kotlin js test task by using this flag in the target
testTask {
enabled = false
}
what about this
When using threadSafeSuspendCallback
, when the callback completes, the completion
callback gets called but it doesn't return back to the call point.
For a small reproduction
Here's my dispatcher:
object IosMainDispatcher : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatch_get_main_queue()) { block.run() }
}
}
And here's my function:
actual suspend fun uploadToS3(
file: String,
userId: String
): String = threadSafeSuspendCallback { completion ->
val objectKey = "my-object-key"
val expression = AWSS3TransferUtilityMultiPartUploadExpression()
expression.setValue(value = "public-read", forRequestHeader = "x-amz-acl")
val continueHandler: AWSContinuationBlock
continueHandler = {
val error = it?.error()
if (error != null) {
completion(Result.failure(Throwable(error.localizedDescription)))
}
}
continueHandler.freeze()
val completionHandler: AWSS3TransferUtilityMultiPartUploadCompletionHandlerBlock
completionHandler = { _, error ->
if (error != null) {
completion(Result.failure(Throwable(error.localizedDescription)))
}
completion(Result.success("myURL"))
}
completionHandler.freeze()
val awsS3TransferUtility = AWSS3TransferUtility.S3TransferUtilityForKey(TRANSFER_UTILITY_KEY) ?: throw Exception("No Transfer Utility")
awsS3TransferUtility.uploadFileUsingMultiPart(
NSURL.fileURLWithPath(file),
objectKey,
"image/jpeg",
expression,
completionHandler
).continueWithBlock(continueHandler)
return@threadSafeSuspendCallback {
throw Exception("Cancelled")
}
}
This function completed but it doesn't return to the call site.
fun upload() {
CoroutineScope(IosMainDispatcher).launch {
uploadToS3(...) <-- Gets stuck here even when it completes
}
}
Upon talking with @benasher44, this is because the dispatcher doesn't implement the delay. So to fix this, we need to implement the delay.
@UseExperimental(InternalCoroutinesApi::class)
object IosMainDispatcher : CoroutineDispatcher(), Delay {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatch_get_main_queue()) { block.run() }
}
override fun scheduleResumeAfterDelay(
timeMillis: Long,
continuation: CancellableContinuation<Unit>
) {
dispatch_after(timeMillis.times(1000).toULong(), dispatch_get_main_queue()) {
continuation.resume(Unit)
}
}
}
Ticket to track 1.3.70 support. Mostly waiting on a 1.3.70-compatible version of kotlinx.coroutines.
It would help if there is sample project, that could be downloaded and run on ios/jvm (as separate applications).
It could show example when use of coroutineworker eliminate need to write platform specific code.
Now it is not clear, how much boilerplate code required for examples in readme.md.
I am trying to use Ktor HttpClient on background thread using Coroutineworker but I am getting this exception on iOS when I call CoroutineWorker.execute {HttpClient().post("URL")}
Uncaught Kotlin exception: kotlin.Error: Ktor native HttpClient requires kotlinx.coroutines version with `native-mt` suffix (like `1.3.9-native-mt`). Consider checking the dependencies.
at 0 shared 0x000000010e49592d kfun:kotlin.Throwable#<init>(kotlin.String?){} + 93 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/Throwable.kt:23:37)
at 1 shared 0x000000010e48e65b kfun:kotlin.Error#<init>(kotlin.String?){} + 91 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/Exceptions.kt:12:44)
at 2 shared 0x000000010e817da9 kfun:io.ktor.client.utils#checkCoroutinesVersion(){} + 553 (/Users/administrator/Documents/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/posix/src/io/ktor/client/utils/CoroutineUtilsPosix.kt:29:15)
at 3 shared 0x000000010e7c8ba9 kfun:io.ktor.client.HttpClient#<init>(io.ktor.client.engine.HttpClientEngine;io.ktor.client.HttpClientConfig<out|io.ktor.client.engine.HttpClientEngineConfig>){} + 2393 (/Users/administrator/Documents/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt:135:9)
at 4 shared 0x000000010e7c9787 kfun:io.ktor.client.HttpClient#<init>(io.ktor.client.engine.HttpClientEngine;io.ktor.client.HttpClientConfig<out|io.ktor.client.engine.HttpClientEngineConfig>;kotlin.Boolean){} + 135 (/Users/administrator/Documents/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt:81:9)
at 5 shared 0x000000010e7c802b kfun:io.ktor.client#HttpClient(io.ktor.client.engine.HttpClientEngineFactory<0:0>;kotlin.Function1<io.ktor.client.HttpClientConfig<0:0>,kotlin.Unit>){0§<io.ktor.client.engine.HttpClientEngineConfig>}io.ktor.client.HttpClient + 811 (/Users/administrator/Documents/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClient.kt:43:18)
at 6 shared 0x000000010e815d06 kfun:io.ktor.client#HttpClient(kotlin.Function1<io.ktor.client.HttpClientConfig<*>,kotlin.Unit>){}io.ktor.client.HttpClient + 614 (/Users/administrator/Documents/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt:18:46)
at 7 shared 0x000000010e815f12 kfun:io.ktor.client#HttpClient$default(kotlin.Function1<io.ktor.client.HttpClientConfig<*>,kotlin.Unit>?;kotlin.Int){}io.ktor.client.HttpClient + 290 (/Users/administrator/Documents/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/posix/src/io/ktor/client/HttpClient.kt:16:15)
at 8 shared 0x000000010e436077 kfun:com.shared.shared.data.SampleLoggingService.$logData$lambda-0COROUTINE$0.invokeSuspend#internal + 2967
at 9 shared 0x000000010e437d90 kfun:com..shared.shared.data.SampleLoggingService.$logData$lambda-0COROUTINE$0.invoke#internal + 256
at 10 shared 0x000000010e8b6078 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-2$lambda-1COROUTINE$8.invokeSuspend#internal + 712 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/CoroutineWorker.kt:101:33)
at 11 shared 0x000000010e8b65d0 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-2$lambda-1COROUTINE$8.invoke#internal + 256 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/CoroutineWorker.kt:99:40)
at 12 shared 0x000000010e64caa3 kfun:kotlinx.coroutines.intrinsics#startUndispatchedOrReturn@kotlinx.coroutines.internal.ScopeCoroutine<0:0>(0:1;kotlin.coroutines.SuspendFunction1<0:1,0:0>){0§<kotlin.Any?>;1§<kotlin.Any?>}kotlin.Any? + 899 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt:93:2)
at 13 shared 0x000000010e5f3ebf kfun:kotlinx.coroutines#coroutineScope(kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0§<kotlin.Any?>}0:0 + 431 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/CoroutineScope.kt:194:19)
at 14 shared 0x000000010e8b6d4d kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-2COROUTINE$9.invokeSuspend#internal + 1437 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/CoroutineWorker.kt:99:25)
at 15 shared 0x000000010e8b73f0 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-2COROUTINE$9.invoke#internal + 256 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/CoroutineWorker.kt:94:24)
at 16 shared 0x000000010e8b2646 kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$performWorkHandlingExceptions$lambda-9COROUTINE$5.invokeSuspend#internal + 726 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/BackgroundCoroutineWorkQueueExecutor.kt:138:26)
at 17 shared 0x000000010e4b7016 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 758 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/coroutines/ContinuationImpl.kt:30:39)
at 18 shared 0x000000010e64034f kfun:kotlinx.coroutines.DispatchedTask#run(){} + 2719 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt:40:29)
at 19 shared 0x000000010e5f9104 kfun:kotlinx.coroutines.EventLoopImplBase#processNextEvent(){}kotlin.Long + 820 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/EventLoop.common.kt:274:18)
at 20 shared 0x000000010e64e82a kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 2170 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:65:44)
at 21 shared 0x000000010e64d85d kfun:kotlinx.coroutines#runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0§<kotlin.Any?>}0:0 + 1261 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:50:22)
at 22 shared 0x000000010e64dd8d kfun:kotlinx.coroutines#runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>;kotlin.Int){0§<kotlin.Any?>}0:0 + 333 (/opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/Builders.kt:33:8)
at 23 shared 0x000000010e8b1549 kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.enqueueWork$lambda-7$lambda-6#internal + 217 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/BackgroundCoroutineWorkQueueExecutor.kt:112:29)
at 24 shared 0x000000010e8b330b kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$enqueueWork$lambda-7$lambda-6$FUNCTION_REFERENCE$7.invoke#internal + 59 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/BackgroundCoroutineWorkQueueExecutor.kt:111:42)
at 25 shared 0x000000010e8b336b kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$enqueueWork$lambda-7$lambda-6$FUNCTION_REFERENCE$7.$<bridge-UNN>invoke(){}#internal + 59 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/BackgroundCoroutineWorkQueueExecutor.kt:111:42)
at 26 shared 0x000000010e8ba364 kfun:com.autodesk.coroutineworker.WorkerPool.performWork$lambda-1#internal + 308 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/WorkerPool.kt:65:17)
at 27 shared 0x000000010e8ba73f kfun:com.autodesk.coroutineworker.WorkerPool.$performWork$lambda-1$FUNCTION_REFERENCE$18.invoke#internal + 63 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/WorkerPool.kt:63:43)
at 28 shared 0x000000010e8ba79b kfun:com.autodesk.coroutineworker.WorkerPool.$performWork$lambda-1$FUNCTION_REFERENCE$18.$<bridge-UNN>invoke(){}#internal + 59 (/Users/basher/Code/coroutineworker/src/nativeMain/kotlin/com/autodesk/coroutineworker/WorkerPool.kt:63:43)
at 29 shared 0x000000010e4c5437 WorkerLaunchpad + 183 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:69:54)
My project is using
ktorVersion = "1.4.2"
coroutinesVersion = "1.3.9-native-mt-2"
When trying to build the scheme (in XCode) for my multiplatform module I get:
e: Could not find "/users/me/.gradle/caches/modules-2/files-2.1/com.autodesk/coroutineworker-iosx64/0.5.0/1290d0c69a1bd5384577d2acf1d58d15b1bec/coroutineworker.klib" in [/dir/to/myproject/ios/Pods, /users/me/.konan/klib, /users/me/.konan/kotlin-native-macos-1.3.61/klib/common, /users/me/.konan/kotlin-native-macos-1.3.61/klib/platform/ios_x64].
Caused by simply adding the library to my gradle file:
implementation("com.autodesk:coroutineworker:0.5.0")
We are trying to build our app for tvOS target, using coroutineworker, but can not compile it for this target because of no support for tvOS yet. Is it possible to add support for tvOS for coroutineworker?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.