GithubHelp home page GithubHelp logo

autodesk / coroutineworker Goto Github PK

View Code? Open in Web Editor NEW
371.0 11.0 24.0 328 KB

Kotlin Coroutine-based workers for native

License: Apache License 2.0

Kotlin 100.00%
kotlin kotlin-coroutines coroutines kotlin-native kotlin-multiplatform multiplatform

coroutineworker's Introduction

CoroutineWorker

Build Status

Maven Central

Specs

  • Supported on Native, JVM, and JS (legacy and IR) (feel free to contribute adding more targets)
  • Kotlin 1.7.10

Gradle

To use in your multiplatform project, update your common dependencies in your gradle configuration:

kotlin {
    sourceSets {
        commonMain {
            dependencies {
                implementation "com.autodesk:coroutineworker:0.8.3"
            }
        }
    }
}

CoroutineWorker uses gradle module metadata. We recommend adding the following to your settings.gradle to take advantage of that (not necessary for Gradle 6+):

enableFeaturePreview('GRADLE_METADATA')

About

CoroutineWorker helps support multi-threaded coroutine usage in common code that works in Kotlin/Native and on JVM until kotlinx.coroutines has full support for native, multi-threaded coroutines.

Projects Using this on your Devices

Sample Usage

Spawning Asynchronous Work

Use execute to start background work from common code:

val worker = CoroutineWorker.execute {
  // - In here, `this` is a `CoroutineScope`
  // - Run suspend functions, call launch, etc.
  // - This code runs in a thread pool
}

// Tells the worker to cancel (uses standard coroutine cancellation)
worker.cancel()

// Tells the worker to cancel; it suspends until cancellation is finished
worker.cancelAndJoin()

Waiting on Asynchronous Work to Complete

From a coroutine context (i.e. somewhere you can call a suspend fun), use withContext to kick off work to another thread. It will non-blocking/suspend wait for the cross-thread work to complete:

suspend fun doWork() {
  val result = CoroutineWorker.withContext {
    // This is similar to execute, but it returns
    // the result of the work at the end of this lambda
    1
  }
  print(result) // prints 1
}

This is like using withContext on JVM to switch coroutine contexts. You can also properly pass a dispatcher, which will be used on JVM: withContext(Dispatchers.IO) { … }. The idea here is that this will be easy to migrate when we do get multi-threaded coroutine support in Kotlin/Native.

Waiting on Asynchronous Callback-based Work

Use threadSafeSuspendCallback to bridge callback-style async work into your code as a suspend fun:

suspend fun performNetworkFetch() {
  val result = threadSafeSuspendCallback { completion ->
    // example: fetch network data that isn't coroutine-compatible
    fetchNetworkData { networkResult ->
      // notify that async work is complete
      completion(networkResult)
    }
  }

  // result is now available here
}

Sample Project

In the sample directory, there is a sample project that demonstrates adding CoroutineWorker to an iOS + JVM library. We just used the sample library from IntelliJ's template for a "Mobile Shared Library." In the sample is a function called performWork (common code) that takes a completion lambda and demonstrates CoroutineWorker.execute. In tests, we use K/N concurrency helpers from kotlinx.atomicfu to demonstrate capturing a result across threads in K/N and executing this function.

CoroutineWorker Prefers Frozen State

Object detachment (i.e. transferring object ownership from one thread to another) is relatively difficult to achieve (outside of simple scenarios) compared to working with objects that are frozen and immutable. Because of this, CoroutineWorker prefers taking the frozen, immutable route:

  • Lambdas passed to CoroutineWorker are automatically frozen when they are going to be passed across threads.
  • The result value from withContext is also frozen.

Tips for Working with Frozen State

  • Be careful about what your frozen lambdas capture; those objects will be frozen too. Especially, watch for implicit references to this.
  • Call ensureNeverFrozen() on objects that you don't expect to ever be frozen.

IO-Bound Work

In the JVM world, you typically write code like this for managing IO-bound work with coroutines:

withContext(Dispatchers.IO) {
    // IO writes
}

Similar behavior is supported in CoroutineWorker for Kotlin/Native via the IODispatcher. To use it in common code, make an expect val Dispatchers.IO: CoroutineDispatcher that returns IODispatcher for Kotlin/Native and Dispatchers.IO for JVM, and pass that to CoroutineWorker.withContext when performing IO-bound worker.

coroutineworker's People

Contributors

0xcf843ecf802c722f434d56 avatar benasher44 avatar c2h6o avatar danielrbaird avatar darran-kelinske-fivestars avatar elevenfive avatar elkhoudiry avatar jessesquires avatar lavruk avatar louiscad avatar vasarhelyia avatar vonox7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

coroutineworker's Issues

CoroutineWorker vs Coroutines-MT

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?

example project could help with adoption

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.

Error building once including library into gradle file:

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")

threadSafeSuspendCallback completes but does not return back

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)
        }
    }
}

Kotlin 1.3.60

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.

Ktor-client inside CoroutineWorker.execute - Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread

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?

iOS app crashes when using IODispatcher

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

kotlin js test fail ignore ??

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

The number of workers should default to the number of processors rather than a fixed 4

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.

private val executor = BackgroundCoroutineWorkQueueExecutor<WorkItem>(4)

Missing examples

Documentation makes references to examples. No examples are found in current version

Can´t get the result on the Main Thread

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??

1.3.70 Support

Ticket to track 1.3.70 support. Mostly waiting on a 1.3.70-compatible version of kotlinx.coroutines.

Ktor native HttpClient requires kotlinx.coroutines version with `native-mt`

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"

Support for tvOS target

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?

I think it's time to archive

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.