is anyone able to dispatch to a background queue f...
# kotlin-native
k
is anyone able to dispatch to a background queue from kotlin? it looks like the lambda that you pass it needs to be frozen?
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared com.airwatch.test.SendTestRunnerTestIos.$concurrency test$lambda-0$FUNCTION_REFERENCE$5@3e40b0e8 from other thread
I am trying to emulate a call from an iOS app, but I can't do that if the lambda has to be frozen
weird, freezing it doesn't even seem to fix it
ah, needed to move the block back in the parens
k
You definitely need to freeze the block (which freezes whatever it captures, just FYI)
k
i'm aware, unfortunately
this implementation is so nice and straightforward for JVM, and now I am going to have to introduce a bunch of complexity to get it working on native
k
I’m working on a plugin to give you a heads up on captured state. The general solution is to cut down on the state you’re capturing in the lambda. I don’t know what you’re working on, so that may indeed make things ugly, but in most cases it hasn’t been too bad. The big exception being when you capture fields of a model class. You wind up freezing a bunch of things
k
i have an object that is essentially a homegrown test runner, and it has one method that is designed to be called by the app from a brackground thread, but that whole idea just doesn't work for Native
because even referencing the runner from a background thread is an exception
k
The object itself is created in another thread?
k
it's created on the main thread
k
Would need to see it to comment more, but it sounds like a thing that would get complex with native.
k
indeed it is
i am going to start by exploring returning a frozen object that can use coroutines to transfer control back the main thread... but i know that having to freeze things will likely end up making this a no go
yep, the job is getting frozen, and the job must be mutable
k
If there’s a way to show some code, would be easier to comment on
k
i can probably piece the important parts together into a gist
it's a little messy because i've been trying to hack together something that works... https://gist.github.com/wongk/d770b899acbce719cba6294e719df28e
k
There’s a lot going on there for sure. When you say “Job” you mean the thing you’re trying to run, not the coroutine “Job” right? In this piece of code, what is being frozen that you would expect not to be?
k
no, i mean the coroutine job
it's frozen, and it can't work that way
k
What if you use the multithreaded coroutines?
k
however, I was able to move the coroutine scope declaration to the companion object, and that fails differently (it hangs, I assume because I am reading from and sending to the channel both on the main thread)
multithreaded coroutines carry all the same restrictions as worker... which will essentially mean I will have to completely refactor this class
k
By restrictions do you mean the state/freezing?
k
yes
k
Well, I feel like you’re going to have a really hard time doing significant concurrency work in native and not refactoring, but I guess it depends how you do it
k
i've exhausted my options for not refactoring w/o finding a solution
(that can think of, anyway)
i was hoping somehow some run loop magic or something would allow both ends of the channel to be used on the same thread
k
Don’t know. I’m not super experienced with channels
k
i can tell you it deadlocks 😛
k
Running into similar. Concurrent testing is not fun
k
hot damn ... reading this I think the new coroutines preview can support my use case
All core communication and synchronization objects in 
kotlin.coroutines
 such as Job, Deferred, Channel, BroadcastChannel, Mutex, and Semaphore are shareable. It means that they can be frozen for sharing with another thread and still continue to operate normally.
a channel is exactly what I need to share
k
Oh, yeah. That’s what I was tallking about. We’re using that in some almost-prod code
k
this is an internal tool so I am not concerned about it's experimental state
oh my lord it worked
all I need to do is add 1 extra class to wrap the channel that can be used from non-main threads
k
Nice