<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Galligan</title>
    <description>The latest articles on DEV Community by Kevin Galligan (@kpgalligan).</description>
    <link>https://dev.to/kpgalligan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38307%2Fca5f5c08-ec38-421d-aaee-0bff7a29069e.png</url>
      <title>DEV Community: Kevin Galligan</title>
      <link>https://dev.to/kpgalligan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kpgalligan"/>
    <language>en</language>
    <item>
      <title>Ktor and Kotlin/Native</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Tue, 01 Sep 2020 20:07:01 +0000</pubDate>
      <link>https://dev.to/kpgalligan/ktor-and-kotlin-native-3g7n</link>
      <guid>https://dev.to/kpgalligan/ktor-and-kotlin-native-3g7n</guid>
      <description>&lt;h1&gt;
  
  
  Ktor and Kotlin/Native
&lt;/h1&gt;

&lt;p&gt;The story of coroutines for Kotlin/Native has been complex for a while now, and with the news that &lt;a href="https://blog.jetbrains.com/kotlin/2020/07/kotlin-native-memory-management-roadmap/"&gt;the Kotlin/Native memory model will be changing&lt;/a&gt;, coroutines for Kotlin/Native will remain a complex story for some time.&lt;/p&gt;

&lt;p&gt;Ktor is built around coroutines. The coroutines situation fundamentally affects how Ktor functions. There have been multiple moving targets in this story, which has created a lot of confusion and a number of bug reports that kind of cross over the same core issues.&lt;/p&gt;

&lt;p&gt;In this post, I will attempt to add some clarity to the situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Coroutines Situation
&lt;/h2&gt;

&lt;p&gt;To be clear, when we're talking about "core&lt;br&gt;
utines", we're generally talking about kotlinx.coroutines. It's technically a separate library, but I can't imagine a realistic situation where you'd actually use coroutines and not include kotlinx.coroutines.&lt;/p&gt;

&lt;p&gt;Initially, kotlinx.coroutines for Kotlin/Native was single threaded. You could suspend execution, but not schedule work on different threads. This was due to Kotlin/Native's memory model.&lt;/p&gt;

&lt;p&gt;Ktor was designed to run on this single-threaded model. Also, as far as I know on iOS, you would need to initiate Ktor calls from the main thread.&lt;/p&gt;

&lt;p&gt;In late 2019, a draft PR emerged which allowed kotlinx.coroutines to communicate across threads. We'll call this the "MT" branch, for "multithreaded". From this branch, there have been parallel library releases. The current main release is '1.3.9' and the current multithreaded release is '1.3.9-native-mt'.&lt;/p&gt;

&lt;p&gt;Unless something changes, the parallel branch and release model will likely stay the same for kotlinx.coroutines until the Kotlin/Native memory model update is complete.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ktor
&lt;/h2&gt;

&lt;p&gt;Until 1.4, Ktor was still designed to be run with the single-threaded version of kotlinx.coroutines. You &lt;em&gt;could&lt;/em&gt; run it with the MT version, but you had to be very careful to keep the scope you were in to the main thread and make sure it was never frozen.&lt;/p&gt;

&lt;p&gt;It's a little complicated to explain, and not super useful as it's now history, but here it is. Coroutines run in a scope, which has (among other things) a Dispatcher and a Job. When you change the Dispatcher to run code on another thread, that scope gets frozen. Once frozen, everything the Job holds will also be frozen. So, if you were doing something on a background thread in the same scope as something you were doing with Ktor, even if Ktor was only in the main thread, you'd get an InvalidMutabilityException.&lt;/p&gt;

&lt;p&gt;I think one of the more confusing parts is that Ktor would work until you involved that scope in a background process, after which it would stop working.&lt;/p&gt;

&lt;p&gt;To see this in action, watch the video.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vqyv5q5NqVE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;To get around this, you either need to maintain a different scope for Ktor, and make sure it never got frozen, or isolate the Job. &lt;a href="https://github.com/touchlab/KaMPKit/blob/45e20c85b42beea9d2a14ad2819ade135f5b56cd/shared/src/iosMain/kotlin/co/touchlab/kampkit/ktor/Platform.kt"&gt;We did that with KaMPKit&lt;/a&gt;. It was a pretty ugly hack, but it worked.&lt;/p&gt;

&lt;p&gt;Also, since Ktor depended on the non-MT version, you could unintentionally be using the non-MT version of kotlinx.coroutines even though your dependency configuration explicitly asked for it. You would need to specify that you wanted to use that version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9-native-mt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;version&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;strictly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.3.9-native-mt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Kotlin and Ktor 1.4 release
&lt;/h2&gt;

&lt;p&gt;The 1.4 release of Ktor actually fixes this issue. We didn't hear about it for a bit, but I think that was because the issue was confusing to a lot of folks. Although it's fixed for the MT branch, the situation has some further confusion, as the current release of Ktor pulls in the MT branch of kotlinx.coroutines. &lt;strong&gt;If your project expects the single-threaded version of kotlinx.coroutines, this situation can result in some unexpected behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To experiment with Ktor in the different versions, you can check out our little sample app.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab-lab"&gt;
        touchlab-lab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab-lab/ktorcoroutines"&gt;
        ktorcoroutines
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Just showing ktor fix in 1.4.0
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;The master branch has 1.3.72 and shows the failure that was happening. The kotlin_140 branch has the updated versions and a functional Ktor sample.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;

&lt;p&gt;Ktor needs to be run from the main thread. There are also issues with Ktor and testing, related to the threading restrictions. We'll be digging into this more at some point. Just be aware of it.&lt;/p&gt;

&lt;p&gt;Also, Russell tells me there's a &lt;a href="https://youtrack.jetbrains.com/issue/KTOR-924"&gt;logging issue&lt;/a&gt; which I'm not even going to dig into right now because I want to publish this today…&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;Ktor and kotlinx.coroutines were not working well together on native before 1.4. Now they cooperate better. Using Ktor 1.4 will possibly pull in the MT branch of kotlinx.coroutines, so if your project is not designed for that, be aware that it's possibly an issue.&lt;/p&gt;

&lt;p&gt;We've updated KaMP Kit to remove the hack we had put in. Ktor is now just regular Ktor&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab"&gt;
        touchlab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab/KaMPKit"&gt;
        KaMPKit
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      KaMP Kit by Touchlab is a collection of code and tools designed to get your mobile team started quickly with Kotlin Multiplatform.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Kotlin/Native Concurrency Changes…</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Mon, 20 Jul 2020 20:00:19 +0000</pubDate>
      <link>https://dev.to/touchlab/kotlin-native-concurrency-changes-p3e</link>
      <guid>https://dev.to/touchlab/kotlin-native-concurrency-changes-p3e</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/xi49yirJiEA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;On the JetBrains Blog, Roman Elizarov just dropped &lt;a href="https://blog.jetbrains.com/kotlin/2020/07/kotlin-native-memory-management-roadmap/"&gt;a pretty big piece of news&lt;/a&gt;, if you're in the Kotlin/Native and Multiplatform world.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you still have questions after reading this post and want our input, &lt;a href="https://touchlabwaitlist.typeform.com/to/gJ6Fw7Oq"&gt;submit your KN concurrency questions&lt;/a&gt; and we’ll get back to you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The explicitly thread-confined, "frozen" concurrency model, is changing.&lt;/p&gt;

&lt;p&gt;I've been &lt;a href="https://www.youtube.com/watch?v=Dul17VSiejo"&gt;talking&lt;/a&gt; &lt;a href="https://www.youtube.com/watch?v=oxQ6e1VeH4M"&gt;about&lt;/a&gt; this concurrency and runtime model for the past 2+ years. From a safety perspective, there's a lot to like. Unrestricted shared memory access is problematic, to put it mildly. Enforcing some rules at runtime means extra safety, and forces you to think about how your JVM code is architected. Maybe it could be done differently?&lt;/p&gt;

&lt;p&gt;Of course, if I take a step back, I've done a lot of content explaining this model over the past couple of years. That would imply that, perhaps, it is difficult for developers to learn. It is certainly a unique model, and the fact that the JVM and Native live by different rules has been a source of some confusion indeed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unpacking The Post
&lt;/h2&gt;

&lt;p&gt;I want to highlight some parts of the post and discuss them a bit.&lt;/p&gt;

&lt;p&gt;The most important bit was in the TL;DR:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Existing code will continue to work and will be supported."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is important to stress that this post is talking about future changes, and that your Native code will be compatible with these future changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"To solve these problems, we've started working on an alternative memory manager for Kotlin/Native that would allow us to lift restrictions on object sharing in Kotlin/Native…"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means the runtime-enforced thread-confinement model will be going away. There was some confusion about what "object sharing" meant. That's not just global objects. It's the full memory management model.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We plan to introduce it in a way that is mostly compatible with existing code, so code that is currently working will continue to work."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"mostly compatible" might sound like a concern, but unless you have something really exotic going on, it should work fine. Freezing will still be there, but it'll be optional (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#:~:text=A%20frozen%20object%20can%20no,existing%20properties%20from%20being%20changed."&gt;like Javascript&lt;/a&gt;). The annotations will still have implementations, even if they no longer do anything.&lt;br&gt;
Your code will continue to work, and in many cases, work faster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"and we will be looking at ways to improve Kotlin's approach to working with immutable data in the whole Kotlin language, not just in Kotlin/Native."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This part is interesting. The fact that the JVM and Native worked differently at runtime was one of the biggest issues. Improving immutable data in the language, and applying that to concurrent best practices, sounds like a good thing, but we'll have to see what emerges.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Meanwhile, we'll continue to support the existing memory manager, and we'll release multithreaded libraries for Kotlin/Native so you can develop your applications on top of them."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is important. For our apps, we use the multithreaded coroutines branch. We're careful to use it in such a way as to avoid the potential memory leaks discussed in Roman's post, but it is a core part of the library ecosystem. There will be ongoing support for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What now?
&lt;/h2&gt;

&lt;p&gt;Well, personally, I'm going to find other things to talk about at conferences :)&lt;/p&gt;

&lt;p&gt;Other than that, not a whole lot changes &lt;strong&gt;right now&lt;/strong&gt;. There's no timeline on the memory manager updates, but you can assume it'll be quite a while. This isn't a few months away. That means, for the foreseeable future, if you write Kotlin/Native code, you'll need to understand the frozen model and how to write code in it. All the stuff we've been talking about still applies.&lt;/p&gt;

&lt;p&gt;KMP continues to mature as a platform, and the concurrent code you write for Native now will continue to work whenever these updates arrive.&lt;/p&gt;

&lt;p&gt;I think we (Touchlab) may start producing content around how to accomplish certain tasks, rather than deeper explanations around the fundamentals ("frozen", etc). Tech recipes, basically. For example, how to use Flow and Sqldelight, how to handle networking in various scenarios, etc. You can mostly hide the details of the current memory model, and you can write code that will transition well when these changes do come.&lt;/p&gt;

&lt;p&gt;So, not a whole lot changes right now, but changes certainly are coming. Ultimately, this will improve adoption, which is good for the ecosystem. I'm sure I'll have more to say down the road…&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinnative</category>
      <category>android</category>
      <category>kotlinmultiplatform</category>
    </item>
    <item>
      <title>Debugging Kotlin on iOS with Xcode</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Thu, 19 Mar 2020 18:59:36 +0000</pubDate>
      <link>https://dev.to/touchlab/debugging-kotlin-on-ios-with-xcode-37fd</link>
      <guid>https://dev.to/touchlab/debugging-kotlin-on-ios-with-xcode-37fd</guid>
      <description>&lt;p&gt;Being able to attach a debugger to any code you're running is a pretty useful tool. We expect these tools to mature for Kotlin Multiplatform, especially later this year when the &lt;a href="https://www.infoworld.com/article/3509457/jetbrains-bringing-ios-device-support-to-android-studio.html"&gt;Android Studio plugin launches&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For sharing Kotlin code with iOS projects, it would seem pretty important to be able to debug directly in Xcode. We built the &lt;a href="https://github.com/touchlab/xcode-kotlin"&gt;Kotlin Xcode plugin&lt;/a&gt; to make that possible.&lt;/p&gt;

&lt;p&gt;Plugins are no longer officially supported in Xcode, of course. However, they haven't been entirely disabled for source code formatting and custom languages. There are &lt;a href="https://github.com/apollographql/xcode-graphql"&gt;several of&lt;/a&gt; &lt;a href="https://github.com/mtak-/rust-xcode-plugin"&gt;these&lt;/a&gt; out in the wild which are doing roughly the same thing. Color source code, and tell Xcode you can debug these files.&lt;/p&gt;

&lt;p&gt;From there, Xcode just hooks into lldb, so as long as your source type supports lldb, you should be able to debug!&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing
&lt;/h2&gt;

&lt;p&gt;Installing the Xcode plugin is a little tricky. As plugins aren't officially supported, Xcode doesn't make the process easy, and it changed somewhat between v10 and v11. Follow the instructions in the &lt;a href="https://github.com/touchlab/xcode-kotlin/blob/master/README.md"&gt;readme&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some things to note. If you have the plugin installed already, but it seems to have stopped working, you &lt;em&gt;may&lt;/em&gt; need to completely remove the plugin and reinstall. That means close Xcode, open &lt;code&gt;~/Library/Developer/Xcode/Plug-ins/&lt;/code&gt; and remove &lt;code&gt;Kotlin.ideplugin&lt;/code&gt;, open Xcode again, close, and run &lt;code&gt;setup.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why that happens is unknown, but that seems to solve the issue. We may eventually make an installer process to automate that, but we need more testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Kotlin
&lt;/h2&gt;

&lt;p&gt;Currently you'll need a dynamic framework to debug. We are working on getting debugging to work with static frameworks, but at present, that doesn't work right.&lt;/p&gt;

&lt;p&gt;If you aren't using the Kotlin Cocoapods plugin, you should have a dynamic framework by default. If you are using the Cocoapods plugin, that generates static frameworks, and there's no way to disable that directly. We've forked the Cocoapods plugin so you can generate dynamic frameworks for Kotlin with Cocoapods.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab"&gt;
        touchlab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab/KotlinCocoapods"&gt;
        KotlinCocoapods
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;For a live example, there's a &lt;a href="https://github.com/touchlab/KaMPKit/pull/76"&gt;PR to KaMP Kit&lt;/a&gt; pending to enable debugging.&lt;/p&gt;

&lt;p&gt;Some notes. You need to do a clean build to get changes to show up in Xcode. Not a full clean of Kotlin's build, but in Xcode, run "Clean Build Folder". We have &lt;a href="https://github.com/touchlab/KotlinCocoapods/issues/1"&gt;an issue for this&lt;/a&gt; and will look into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kotlin Files in Xcode
&lt;/h2&gt;

&lt;p&gt;Previously we recommended to use &lt;a href="https://github.com/touchlab/KotlinXcodeSync"&gt;our KotlinXcodeSync plugin&lt;/a&gt; to sync xcode with Kotlin files. As it turns out, there's &lt;a href="https://github.com/touchlab/xcode-kotlin/issues/16"&gt;a much easier way&lt;/a&gt; to see your Kotlin in Xcode. You can just add a folder reference, which will make the files available but won't try to compile them directly or put them in the app bundle.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/p_xdEOiqvSA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;We'll be deprecating the Xcode Sync gradle plugin, and writing up some better docs for all of this soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;We're waiting on Kotlin 1.3.71 to finish pushing some libraries, and will be revisiting the dev tools and process at that point to streamline things a bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reach Out
&lt;/h2&gt;

&lt;p&gt;If your org is looking for expert support to get started on your KMP journey, of course, &lt;a href="https://touchlab.co/"&gt;reach out&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Kotlin/Native - Isolated State</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Sun, 26 Jan 2020 19:40:27 +0000</pubDate>
      <link>https://dev.to/touchlab/kotlin-native-isolated-state-50l1</link>
      <guid>https://dev.to/touchlab/kotlin-native-isolated-state-50l1</guid>
      <description>&lt;p&gt;In the previous post we discussed transferring state. I started there because recently several people posted in the Kotlin slack discussing &lt;code&gt;DetachedObjectGraph&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In my particular journey from JVM to Kotlin/Native (or KN), I went through a phase I think many new KN devs go through. In the JVM I was used to sharing mutable state between threads, and I assumed I must retain that ability at all costs. &lt;code&gt;DetachedObjectGraph&lt;/code&gt; is one of the first things I started to focus on.&lt;/p&gt;

&lt;p&gt;It seems like interest in KMP has picked up considerably this first month of 2020, and so we've had a lot of questions about &lt;code&gt;DetachedObjectGraph&lt;/code&gt;. I have found that &lt;code&gt;DetachedObjectGraph&lt;/code&gt; is of limited value, and once I understood the KN state model, I found I never needed it.&lt;/p&gt;

&lt;p&gt;You will, however, occasionally need mutable state between threads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stately Collections V1
&lt;/h2&gt;

&lt;p&gt;Going back to mid/late 2018, we released Stately. &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab" rel="noopener noreferrer"&gt;
        touchlab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab/Stately" rel="noopener noreferrer"&gt;
        Stately
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Kotlin Multiplatform State Library
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Along with atomics, locks, and some other concurrency support stuff, there was also a set of concurrent collection classes. These internally used &lt;code&gt;AtomicRef&lt;/code&gt; to implement collections. That meant I actually implemented a linked list and a hash map from scratch with &lt;code&gt;AtomicRef&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These collections work, but performance is bad, their implementation is basic, and their use is inflexible. Also, just FYI, &lt;code&gt;AtomicRef&lt;/code&gt; can leak memory, so you need to clear these collections when you're done with them.&lt;/p&gt;

&lt;p&gt;As it turns out, if you just keep your state isolated, you can implement concurrent collections in an almost trivial manner, with far better performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stately Collections V2 (Isolated State)
&lt;/h2&gt;

&lt;p&gt;The next version of Stately will have a class called &lt;code&gt;IsolateState&lt;/code&gt;. You create an instance in a manner similar to how you interact with &lt;code&gt;DetachedObjectGraph&lt;/code&gt;. Pass in a producer lambda. One critical difference. The value returned from that lambda cannot be frozen.&lt;/p&gt;

&lt;p&gt;Once you create this instance of &lt;code&gt;IsolateState&lt;/code&gt;, you interact with it by way of the &lt;code&gt;access&lt;/code&gt; method. &lt;code&gt;access&lt;/code&gt; takes a lambda, which takes one argument: the mutable state.&lt;/p&gt;

&lt;p&gt;As an example, let's create a simple shared map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;StateSample&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;cacheMap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IsolateState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;cacheMap&lt;/code&gt; is a simple mutable map, with &lt;code&gt;String&lt;/code&gt; keys and &lt;code&gt;SomeData&lt;/code&gt; values.&lt;/p&gt;

&lt;p&gt;To be clear, according to KN state rules, &lt;code&gt;object StateSample&lt;/code&gt; is frozen, so &lt;code&gt;cacheMap&lt;/code&gt; is also frozen. The state it contains, the result of &lt;code&gt;mutableMapOf&amp;lt;String, SomeData&amp;gt;()&lt;/code&gt;, is &lt;em&gt;not&lt;/em&gt; frozen, and can never be (we call &lt;code&gt;ensureNeverFrozen()&lt;/code&gt; internally).&lt;/p&gt;

&lt;p&gt;Getting to that state and doing stuff with it is easy:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;doStuff&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nc"&gt;StateSample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cacheMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Getting values from the state is also straightforward:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;readStuff&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateSample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cacheMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sd: $sd, isFrozen: ${sd.isFrozen()}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note, the value returned from &lt;code&gt;access&lt;/code&gt; will be frozen, as is anything captured and passed into &lt;code&gt;access&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There will be a separate &lt;code&gt;stately-iso-collections&lt;/code&gt; module, but because isolated state is so flexible, I'm not sure how necessary a full &lt;code&gt;MutableMap&lt;/code&gt; implementation, for example, would be as opposed to just using &lt;code&gt;access&lt;/code&gt; to get at the methods you need. I didn't want to clutter the middle of the post, but I've included the entire implementation of a &lt;code&gt;MutableMap&lt;/code&gt; using &lt;code&gt;IsolateState&lt;/code&gt; at the bottom. It really is bordering on trivial.&lt;/p&gt;

&lt;p&gt;One of the more inflexible aspects of any concurrent collection is the lack of atomic operations. Calling &lt;code&gt;size&lt;/code&gt; will return a value, but if you want to insert a value based on that result, you could have race conditions.&lt;/p&gt;

&lt;p&gt;Take the following example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;racyInABadWay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
    &lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $size"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $size"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- may result in missed values&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Assume &lt;code&gt;fmap&lt;/code&gt; is a concurrent map from Stately v1 collections. Between the call to get size and the call to put a value, the size could change. Your &lt;code&gt;put&lt;/code&gt; call will be invalid. You could fix this by creating a &lt;code&gt;Lock&lt;/code&gt; instance that's associated with &lt;code&gt;fmap&lt;/code&gt;, then passing them both around, but that's ugly.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;IsolateState&lt;/code&gt;, this is again trivial.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;atomicOperations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isoMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;IsolateState&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;){&lt;/span&gt;
    &lt;span class="n"&gt;isoMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i ${map.size}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data ${map.size}"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Under the hood, all &lt;code&gt;access&lt;/code&gt; calls run on the same thread, so while your block is running, nothing can change the map. You can implement arbitrarily complex atomic operations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Performace
&lt;/h2&gt;

&lt;p&gt;Performance is kind of relative. Inserting 50k elements in a v1 Stately map vs v2 is pretty good.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;times&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50_000&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;v1Time&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;measureTimeMillis&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fmap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frozenHashMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $c"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"v1Time: $v1Time"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;isoTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;measureTimeMillis&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;isomap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IsolateState&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()}&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;isomap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $c"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"isoTime: $isoTime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v1Time: 13785
isoTime: 1937
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Compared to using a regular &lt;code&gt;MutableMap&lt;/code&gt;? Well, not as good.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;normalTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;measureTimeMillis&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;map&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $c"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"normalTime: $normalTime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;isoTime: 1937
normalTime: 201
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Of course, you're crossing thread contexts for each call to the &lt;code&gt;IsolateState&lt;/code&gt; instance. There's a lot of overhead involved. Because &lt;code&gt;IsolateState&lt;/code&gt; is inherently more flexible than a fixed concurrent map implementation, inserting in blocks is pretty easy to implement. The performance boost is dramatic.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;isoBlockTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;measureTimeMillis&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;isomap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IsolateState&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()}&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;outerTimes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outerTimes&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;blockMap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="k"&gt;inner&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;putCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="k"&gt;inner&lt;/span&gt;
                &lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $putCount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $putCount"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;isomap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"isoBlockTime: $isoBlockTime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;normalTime: 201
isoBlockTime: 330
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You've inserted 50k elements into a concurrent map structure in a time that's ~65% slower than a local mutable map. It's "slower", relatively, but that performance is fantastic all things considered. That's also without &lt;code&gt;inline&lt;/code&gt; on any of the &lt;code&gt;IsolateState&lt;/code&gt; methods, which may slightly improve the situation.&lt;/p&gt;

&lt;p&gt;Can you insert in Stately v1's collections in blocks? Sure, but it's rigid, and because they're implemented with &lt;code&gt;AtomicRef&lt;/code&gt;, the performance is dismal.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;v1BlockTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;measureTimeMillis&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fmap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frozenHashMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;outerTimes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outerTimes&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;blockMap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="k"&gt;inner&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;putCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="k"&gt;inner&lt;/span&gt;

                &lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $putCount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $putCount"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;fmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"v1BlockTime: $v1BlockTime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It's the same as inserting values individually.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v1Time: 13785
isoTime: 1937
normalTime: 201
isoBlockTime: 330
v1BlockTime: 13623
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To round out our timing comparison, if you use &lt;code&gt;DetachedObjectGraph&lt;/code&gt; to insert 50k elements, things get much, much worse.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;timeTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;times&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50_000&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;detachedTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;measureTimeMillis&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;detachedMap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SharedDetachedObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;detachedMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data $c"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;detachedMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i $c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"detachedTime: $detachedTime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;detachedTime: 68334
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's about 35x slower than using &lt;code&gt;IsolateState&lt;/code&gt;. It'll also get worse as the size grows because you lose the Big O advantage of a hash map. You could certainly optimize access to &lt;code&gt;DetachedObjectGraph&lt;/code&gt; a bit, but what's the point?&lt;/p&gt;

&lt;p&gt;In summary, use &lt;code&gt;IsolateState&lt;/code&gt; for KMP concurrent state.&lt;/p&gt;

&lt;p&gt;We've published an experimental version of Stately to try this out:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s2"&gt;"co.touchlab:stately-isolate:0.10.2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The documentation hasn't been updated, but you can see samples here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab-lab" rel="noopener noreferrer"&gt;
        touchlab-lab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab-lab/StatelyIsoStateSample" rel="noopener noreferrer"&gt;
        StatelyIsoStateSample
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Stately IsolatedState sample
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;We should have a more formal version soon, pending community feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hiring!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://go.touchlab.co/tldevto" rel="noopener noreferrer"&gt;Touchlab is hiring!&lt;/a&gt; Looking for Android-focused mobile developers, and also for experienced or very interested Kotlin Multiplatform devs. We &lt;em&gt;really&lt;/em&gt; need to find a solid Android dev at this precise moment, though. Just FYI. Remote friendly (US-only, for now). &lt;/p&gt;




&lt;h2&gt;
  
  
  MutableMap Implementation
&lt;/h2&gt;

&lt;p&gt;Here's the code for a &lt;code&gt;MutableMap&lt;/code&gt; implemented with &lt;code&gt;IsolateState&lt;/code&gt;. We're essentially just wrapping &lt;code&gt;mutableMapOf&amp;lt;K, V&amp;gt;()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;mutableMapOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;IsolateState&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;containsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;containsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;containsValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;containsValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MutableEntry&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;putAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;V&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stateHolder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;IsolateState&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;stateHolder&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;MutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;MutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;containsAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;containsAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;MutableIterator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableIterator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;removeAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;retainAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retainAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stateHolder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;IsoMutableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;stateHolder&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;MutableSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;MutableSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;mutableSetOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsoMutableIterator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stateHolder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;StateHolder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableIterator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;IsolateState&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MutableIterator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;stateHolder&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;MutableIterator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hasNext&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasNext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Kotlin/Native - Transferring State</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Sun, 26 Jan 2020 16:28:58 +0000</pubDate>
      <link>https://dev.to/touchlab/kotlin-native-transferring-state-4n8i</link>
      <guid>https://dev.to/touchlab/kotlin-native-transferring-state-4n8i</guid>
      <description>&lt;p&gt;Kotlin/Native (KN) has special rules around state and concurrency. We cover them in usable detail in &lt;a href="https://dev.to/touchlab/practical-kotlin-native-concurrency-ac7"&gt;Practical Kotlin Native Concurrency&lt;/a&gt; and in more detail in &lt;a href="https://www.youtube.com/watch?v=oxQ6e1VeH4M"&gt;KotlinConf 2019: Kotlin Native Concurrency Explained&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are basically two rules. Mutable state can only be accessed by one thread at a time, and immutable state can be shared. When sharing state we freeze it, and mutable state generally stays thread confined. However, you &lt;em&gt;can&lt;/em&gt; pass mutable state between threads. In all of my discussions, I mostly ignore that possibility, because it's fairly impractical and we don't use it anywhere (in production), but today we'll discuss it a bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transferring State
&lt;/h2&gt;

&lt;p&gt;In order to transfer mutable state between threads, you need to make sure there are no external references to it. The &lt;code&gt;Worker.execute&lt;/code&gt; function and the &lt;code&gt;DetachedObjectGraph&lt;/code&gt; constructor both take a &lt;code&gt;producer&lt;/code&gt; function argument. The purpose of this function is to "produce" the state that you want to transfer, in such a way that all external references can be omitted.&lt;/p&gt;

&lt;p&gt;That is the first complication and critical concept to understand. You'll often want to add mutable data to a &lt;code&gt;DetachedObjectGraph&lt;/code&gt; from existing state, but this is syntactically difficult.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;failLocal&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Dat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;assertFails&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;DetachedObjectGraph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Dat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;DetachedObjectGraph&lt;/code&gt; constructor takes a lambda producer argument. In it we try to return &lt;code&gt;d&lt;/code&gt;, but &lt;code&gt;d&lt;/code&gt; is still referenced from outside the lambda, specifically here in the local &lt;code&gt;val d&lt;/code&gt;, so the transfer fails.&lt;/p&gt;

&lt;p&gt;This case is overly simplistic. You can "solve" it with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;directReturn&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;DetachedObjectGraph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;Dat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Dat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Dat&lt;/code&gt; instance returned from the producer has no external references, so you can transfer it. However, use your imagination and extrapolate how difficult it will be to maintain mutable state in a &lt;code&gt;DetachedObjectGraph&lt;/code&gt; and pass it around. It quickly becomes impractical.&lt;/p&gt;

&lt;p&gt;I would abbreviate &lt;code&gt;DetachedObjectGraph&lt;/code&gt; with DOG, but &lt;code&gt;DetachedObjectGraph&lt;/code&gt; is not your friend, and dogs are, so I will use the full name &lt;code&gt;DetachedObjectGraph&lt;/code&gt; and clutter your visual space because we don't like them. Anyway...&lt;/p&gt;

&lt;p&gt;You can build some managed access, with something like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SharedDetachedObject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;adog&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;AtomicReference&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;DetachedObjectGraph&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;detachedObjectGraph&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DetachedObjectGraph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;Any&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;adog&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AtomicReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detachedObjectGraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withLock&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;holder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FreezableAtomicReference&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;producer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;grabAccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;Any&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;adog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DetachedObjectGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TransferMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SAFE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;retult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;
        &lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
        &lt;span class="n"&gt;retult&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;grabAccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;FreezableAtomicReference&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;attach&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attach&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;
        &lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;adog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can find this code in a new &lt;a href="https://github.com/touchlab/Stately/blob/kpg/iso_state/stately-isolate/src/nativeCommonMain/kotlin/co/touchlab/stately/native/SharedDetachedObject.kt#L12"&gt;Stately branch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is somewhat complex to look at, but the concept is relatively simple. You create an instance of &lt;code&gt;SharedDetachedObject&lt;/code&gt; with a producer, similar to the previous examples. The state returned is kept in a &lt;code&gt;DetachedObjectGraph&lt;/code&gt;, and you can access that state with the &lt;code&gt;access&lt;/code&gt; method. From that method you can return a value, although make absolutely sure it isn't the mutable state you're holding in the &lt;code&gt;DetachedObjectGraph&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;detachedObject&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SharedDetachedObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;mutableListOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

&lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50_000&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="n"&gt;rcount&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;detachedObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;access&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"row $rcount"&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;element&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The code above creates a mutable list that can be accessed in a shared way, from multiple threads. Anything leaving the &lt;code&gt;access&lt;/code&gt; lambda that's still referenced from inside it should be frozen, of course (&lt;code&gt;String&lt;/code&gt; gets special treatment in KN. It's always frozen).&lt;/p&gt;

&lt;p&gt;OK! Transferring state may be syntactically messy, but it works, right! Sure, but there's another important consideration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Transferring state requires that you inspect all of the state you want to transfer, to ensure nobody external is referencing it. &lt;em&gt;All&lt;/em&gt; of the state. In the example above, that means on the last run, all 50k entries. Doing that isn't free.&lt;/p&gt;

&lt;p&gt;Imagine a common use case. Building a HashMap cache. One of the primary benefits of a HashMap is read and write time. In the good case, they're constant time. Keeping a map in a &lt;code&gt;DetachedObjectGraph&lt;/code&gt; sounds like a good idea, but each access of the map is followed by detaching so you can put it back in the &lt;code&gt;DetachedObjectGraph&lt;/code&gt; for another thread to use. That turns constant time into linear time. A linear time hash map is a shitty hash map.&lt;/p&gt;

&lt;p&gt;In our simple list case above, the time per-insert grows as the list gets larger.&lt;/p&gt;

&lt;p&gt;We have a new set of concurrent/mutable state holders coming out for Stately. You can see the &lt;a href="https://github.com/touchlab/Stately/tree/kpg/iso_state"&gt;current branch here&lt;/a&gt;. In the next post we'll cover how to use the new state objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hiring!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://go.touchlab.co/tldevto"&gt;Touchlab is hiring!&lt;/a&gt; Looking for Android-focused mobile developers, and also for experienced or very interested Kotlin Multiplatform devs. We &lt;em&gt;really&lt;/em&gt; need to find a solid Android dev at this precise moment, though. Just FYI. Remote friendly (US-only, for now). &lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Kapture - Kotlin/Native State Capture</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Tue, 21 Jan 2020 19:27:33 +0000</pubDate>
      <link>https://dev.to/touchlab/kapture-kotlin-native-state-capture-3m87</link>
      <guid>https://dev.to/touchlab/kapture-kotlin-native-state-capture-3m87</guid>
      <description>&lt;p&gt;Kotlin/Native state is different than what most Kotlin developers would be used to. To be shared between threads, state must be "frozen", which makes it immutable in the runtime.&lt;/p&gt;

&lt;p&gt;For background on Kotlin/Native concurrency and state, see &lt;a href="https://dev.to/touchlab/practical-kotlin-native-concurrency-ac7"&gt;Practical Kotlin Native Concurrency&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once the developer gets the general idea of how this works, it's not too complicated. However, capturing and freezing state unintentionally is a problem. Especially when combined with concurrency libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Library Model
&lt;/h2&gt;

&lt;p&gt;If you use the KN primitive &lt;a href="https://github.com/JetBrains/kotlin-native/blob/master/runtime/src/main/kotlin/kotlin/native/concurrent/Worker.kt"&gt;&lt;code&gt;Worker&lt;/code&gt;&lt;/a&gt; to implement concurrency, you'll need to be very explicit about state transfer or freezing.&lt;/p&gt;

&lt;p&gt;In practice, few developers will use &lt;code&gt;Worker&lt;/code&gt; directly. All current concurrency libraries opt to take a lambda argument that will be frozen, then run on another thread.&lt;/p&gt;

&lt;p&gt;That makes concurrency in KN very simple. New developers often complain about the restrictions of the KN model, but KN forces you to rethink your architecture and be intentional about your mutable state. If you learn to work with the model, it's actually a good thing.&lt;/p&gt;

&lt;p&gt;However, because lambdas can capture state, and freezing aggressively freezes everything it touches, you can easily wind up freezing state unintentionally. This can be very frustrating and lead to a lot of the beginner trouble with KN's model.&lt;/p&gt;

&lt;p&gt;Take the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I've been bitten by this problem on multiple occasions. The method &lt;code&gt;background&lt;/code&gt; is going to take the lambda argument and freeze it, and run &lt;code&gt;saveToDb(id, order)&lt;/code&gt; on another thread. That means &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;order&lt;/code&gt; will be frozen.&lt;/p&gt;

&lt;p&gt;Visually it looks like you're just freezing those two values. &lt;code&gt;order&lt;/code&gt; might be a problem, because we don't know if the &lt;code&gt;Order&lt;/code&gt; type should be frozen, but the real problem here is &lt;code&gt;id&lt;/code&gt; is actually attached to &lt;code&gt;Product&lt;/code&gt;. We wind up freezing the whole &lt;code&gt;Product&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Seeing what state is captured is not always obvious. That is relatively easy to determine with static analysis, and could be surfaced to the developer in the IDE.&lt;/p&gt;

&lt;p&gt;However, not all state is problematic to freeze. In the simple example above, although &lt;code&gt;Product&lt;/code&gt; is frozen, as presented, that's not a problem. There's nothing about &lt;code&gt;Product&lt;/code&gt; that would be mutable anyway.&lt;/p&gt;

&lt;p&gt;However, maybe it looked more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Although perhaps not an architecturally good decision, the code above now has a real issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kapture
&lt;/h2&gt;

&lt;p&gt;Kapture is a code inspection Intellij plugin that finds "hot" functions, collects what state will be captured in the lambda arg(s), and evaluates if that state is problematic to freeze. If so, it'll create an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lisBxDuT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3vglq32slscymh81zy4r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lisBxDuT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3vglq32slscymh81zy4r.gif" alt="Basic id capture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The inspection will add an issue to &lt;code&gt;id&lt;/code&gt;, and hovering over it will pop up a summary of what's wrong and offer some fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Education
&lt;/h2&gt;

&lt;p&gt;The goal of Kapture is not simply to warn you of captured state. The options in the fix list will include links to documentation explaining the issue and potential best-practice approaches to refactoring your state architecture.&lt;/p&gt;

&lt;p&gt;For example, in the scenario above, it's better to cross thread boundaries with a named function and use function parameters to avoid capturing the parent class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Hot Functions
&lt;/h2&gt;

&lt;p&gt;Hot functions are functions that take function arguments and may cross thread boundaries. There are some built-in functions that Kapture recognizes. These include &lt;code&gt;withContext&lt;/code&gt; from corountines, and methods from &lt;code&gt;Flow&lt;/code&gt;. You can also annotate your own with &lt;code&gt;@FreezingBlockCall&lt;/code&gt;. This tells capture to treat &lt;code&gt;block&lt;/code&gt; as special and look at it's captured state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@FreezingBlockCall&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;block&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Sometimes a function won't actually cross a thread boundary at runtime, but it can be difficult to know for sure at compile time. Kapture, in general, leans conservative and will warn you of potential issues in ambiguous cases.&lt;/p&gt;

&lt;p&gt;If you're in the main thread and call the following, you won't actually switch threads (and coroutines shouldn't freeze the lambda), but Kapture treats it as a potentially thread-crossing method anyway.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//What if you were already in the main thread?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Mutability Analysis
&lt;/h2&gt;

&lt;p&gt;How do we determine if something is immutable? In summary, Kapture analyses the captured data. Everything has to be final and immutable.&lt;/p&gt;

&lt;p&gt;For example, the following is OK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, this is not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The val &lt;code&gt;s&lt;/code&gt; is of type &lt;code&gt;Any&lt;/code&gt;, which is not final.&lt;/p&gt;

&lt;p&gt;There are many other rules, including special classes. For example, anything from Sqldelight is considered safe to freeze, so those classes are ignored. On the other end, it's relatively easy to capture test classes, so even if your test class has nothing mutable, it'll be flagged as an issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductTest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DbHelper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;heyTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;whatever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- issue here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can override that, or anything, with @Freezeable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Freezeable&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductTest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DbHelper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;heyTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;whatever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Kapture can also see some calls in the init block, so this would also work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductTest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DbHelper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;heyTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;whatever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are a number of detailed inspections which you can read about in the docs, and more to be added to increase the accuracy. However, the important point to remember is if we can't reasonably verify that you can freeze some state, you'll get an error. It is intentionally conservative.&lt;/p&gt;

&lt;h2&gt;
  
  
  80/20
&lt;/h2&gt;

&lt;p&gt;KN verifies frozen at runtime, which has been a criticism of the model. Doing this at compile-time, like Rust, would be great, but would require a significantly different language. There's only so much the compiler can know about what you're doing without those language changes.&lt;/p&gt;

&lt;p&gt;Kapture operates under the "pretty good" model. It'll make pretty good guesses, and you can override it when it's wrong. "Pretty good" isn't a virtue for compilers, but for developer tools, it's a different story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluation
&lt;/h2&gt;

&lt;p&gt;We're currently looking for private testers to give feedback. We'd like to know if this is actually useful in practice and if it helps explain how the KN state model works. Please sign up here for access.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://go.touchlab.co/Kapture-Devto"&gt;http://go.touchlab.co/Kapture-Devto&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Special Thanks
&lt;/h2&gt;

&lt;p&gt;This idea was kind of a combination of some slides in my concurrency talk, and chats with Eugenio Marletti and Scott Pierce in and around the Kotlin Slack.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Practical Kotlin Native Concurrency Part 3</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Mon, 16 Dec 2019 20:37:50 +0000</pubDate>
      <link>https://dev.to/touchlab/practical-kotlin-native-concurrency-part-3-38p</link>
      <guid>https://dev.to/touchlab/practical-kotlin-native-concurrency-part-3-38p</guid>
      <description>&lt;p&gt;Parts 1 and 2 set the conceptual stage for what we're going to do in Part 3: look at some actual concurrency libraries. We have one more conceptual tool to cover, then we'll go over 2 options for using coroutines in a production app, and discuss Reaktive: a reactive streams implementation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Atomics
&lt;/h1&gt;

&lt;p&gt;KN provides a set of Atomic classes that allow you to have mutable state within a frozen object. In general, it's a good idea to minimize Atomic usage in lieu of "better" architecture, but they can be very useful in cases. Also, when first exposed to KN's state architecture, it can take some time to rethink how architecture should be laid out, and Atomics can help bridge that gap.&lt;/p&gt;

&lt;p&gt;We will be using KN's Atomic primitives directly, but in practice, you'll likely use a library. We publish Stately, but also Atomic-fu has recently added native support. On native they're similar, but on the jvm Atomic-fu has some optimizations and restrictions. You should make an informed decision on which to choose:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab" rel="noopener noreferrer"&gt;
        touchlab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab/Stately" rel="noopener noreferrer"&gt;
        Stately
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Kotlin Multiplatform State Library
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Kotlin" rel="noopener noreferrer"&gt;
        Kotlin
      &lt;/a&gt; / &lt;a href="https://github.com/Kotlin/kotlinx-atomicfu" rel="noopener noreferrer"&gt;
        kotlinx-atomicfu
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The idiomatic way to use atomic operations in Kotlin
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Let's take a look at Atomics in action. We'll be using KN's atomics directly, but either of the two libraries above have equivalent definitions and use KN's atomics under the hood.&lt;/p&gt;

&lt;p&gt;First, let's revert back to the master branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout .
git checkout master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Atomic Primitives
&lt;/h2&gt;

&lt;p&gt;KN provides a set of Atomic classes for integral values: &lt;code&gt;AtomicInt&lt;/code&gt; and &lt;code&gt;AtomicLong&lt;/code&gt;. Those are conceptually simple to use. Run &lt;code&gt;atomicIntDemo()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;atomicIntDemo&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AtomicDataCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;dc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;dc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dc $dc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AtomicDataCounter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;ai&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AtomicInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;AtomicDataCounter&lt;/code&gt; has an &lt;code&gt;AtomicInt&lt;/code&gt; property. We freeze our instance of &lt;code&gt;AtomicDataCounter&lt;/code&gt;, but can still change the &lt;code&gt;AtomicInt&lt;/code&gt; value. You can do this from any thread. Run &lt;code&gt;atomicThreadsDemo()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;atomicThreadsDemo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AtomicDataCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dc ${dc.ai.value}, is frozen ${dc.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;AtomicReference is more generally applicable, as it allows you to have an object reference that can be changed in a frozen object. The object held in the AtomicReference must itself be frozen.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;atomicRefDemo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AtomicDataReference&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🎸"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dr ${dr.ar.value}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AtomicDataReference&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;ar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AtomicReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🚀"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you have global objects that need to have mutable state, this is a straightforward way to manage that state. Global objects visible to multiple threads need to be frozen, so atomics are necessary if you need to change anything. However, there are some things to keep in mind.&lt;/p&gt;

&lt;p&gt;1) Atomic ref performance is obviously not going to be the same as regular mutable state. Freezing isn't free either. Heavy atomic use may not be a great idea if performance is a consideration.&lt;/p&gt;

&lt;p&gt;2) AtomicReference currently should be cleared out if it's not a "forever" object. It is possible to leak memory otherwise. Not always, though. This is something we have on the list for a future blog post. However, the situation may be changing anyway, so this may not be an issue in the near future.&lt;/p&gt;
&lt;h1&gt;
  
  
  Coroutines
&lt;/h1&gt;

&lt;p&gt;The current release version of kotlinx.coroutines operates in a single thread only. Jetbrains has done such a good job associating "concurrency" with "coroutines" that some people in the community confuse the situation to think KN doesn't support concurrency at all.&lt;/p&gt;

&lt;p&gt;Fortunately, that situation is changing. There is a preview branch of kotlinx.coroutines that is functional, and we'll be walking through that. Because it's a preview, including it in a production app may be difficult because of library dependencies, not to mention potential bugs. In the interim there is CoroutineWorker from Autodesk, which provides a source-compatible (ish) implementation for common cases.&lt;/p&gt;
&lt;h2&gt;
  
  
  kotlinx.coroutines Multithreaded Preview
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Kotlin" rel="noopener noreferrer"&gt;
        Kotlin
      &lt;/a&gt; / &lt;a href="https://github.com/Kotlin/kotlinx.coroutines" rel="noopener noreferrer"&gt;
        kotlinx.coroutines
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Library support for Kotlin coroutines 
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;&lt;del&gt;Since this branch has not been officially released, you'll need to build kotlinx.coroutines locally.&lt;/del&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Good News!&lt;/em&gt; There's another prebuilt preview release! You don't need to build locally, at least for now. Just update your sample code...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our handy sample app should be updated as well. Again, clear out local changes, and update, but this time we'll also need to switch branches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout .
git pull
git fetch
git checkout mt_coroutines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will check out the remote &lt;code&gt;mt_coroutines&lt;/code&gt; branch. We've moved the coroutines sample to a separate branch because of the local kotlinx.coroutines dependency. It would fail if you hadn't done the local build.&lt;/p&gt;

&lt;p&gt;Anyway, now we're ready to get started.&lt;/p&gt;

&lt;p&gt;Just an FYI. This post is not a generalized intro to coroutines. We're assuming you understand the basics. We're going to discuss them in the context of native and native's state model &lt;em&gt;only&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Some things to know specific to coroutines on native:&lt;/p&gt;

&lt;p&gt;1) A coroutine is always bound to a single thread. The JVM may use a thread pool for processing. Not so in native.&lt;/p&gt;

&lt;p&gt;2) You create a new threaded coroutine with &lt;code&gt;newSingleThreadContext&lt;/code&gt;. Each is backed by it's own Worker (and therefore, it's own thread).&lt;/p&gt;

&lt;p&gt;3) &lt;code&gt;Dispatchers.Default&lt;/code&gt; is defined, and is a single Worker coroutine.&lt;/p&gt;

&lt;p&gt;4) &lt;code&gt;Dispatchers.Main&lt;/code&gt; is defined for Apple targets. The situation is more complex for Windows/Linux.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://github.com/Kotlin/kotlinx.coroutines/blob/native-mt/kotlin-native-sharing.md" rel="noopener noreferrer"&gt;kotlin-native-sharing.md&lt;/a&gt; for more detail.&lt;/p&gt;

&lt;p&gt;You switch threads by switching the &lt;code&gt;Dispatcher&lt;/code&gt;. In our examples we'll do this with &lt;code&gt;withContext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Something very important to understand: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are switching threads, all data captured will be frozen, and any return value will be frozen.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's look at a basic example. In &lt;code&gt;SampleMacos.kt&lt;/code&gt;, find &lt;code&gt;5) Coroutines&lt;/code&gt;. Run &lt;code&gt;basicBackgroundCoroutine()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;basicBackgroundCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(Coroutine) Is main thread $isMainThread"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(Coroutine) Is main thread $isMainThread"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We create a coroutine context with &lt;code&gt;runBlocking&lt;/code&gt;, then switch to a different thread with &lt;code&gt;withContext(Dispatchers.Default)&lt;/code&gt;. On the console we should see:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(Coroutine) Is main thread true
(Coroutine) Is main thread false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Easy!&lt;/p&gt;

&lt;p&gt;Coroutines aren't magic. They follow the same state rules in native as everybody else. As mentioned, any captured state is frozen before it changes threads.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;captureStateCoroutine()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureStateCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🥶"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(Coroutine) Am I frozen? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(Coroutine) Am I frozen now? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is very similar to &lt;code&gt;captureState()&lt;/code&gt; we ran in Part 2. When &lt;code&gt;sd&lt;/code&gt; moves threads, it's frozen. We should see:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(Coroutine) Am I frozen? false
(Coroutine) Am I frozen now? true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Coroutines follow the same rules, and also have the same potential issues. Run &lt;code&gt;captureTooMuchCoroutine()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureTooMuchCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CountingModelCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//We won't get here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CountingModelCoroutine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
        &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Do some db stuff&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Just like in &lt;code&gt;captureTooMuch()&lt;/code&gt; from Part 2, the whole model gets frozen. How do we fix it? Surprise! Same solution. Run &lt;code&gt;captureArgsCoroutine()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureArgsCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CountingModelSaferCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CountingModelSaferCoroutine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
        &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Doing db stuff with $arg, in main $isMainThread"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Return Values
&lt;/h3&gt;

&lt;p&gt;Unlike our simple &lt;code&gt;background&lt;/code&gt; method, coroutines can return a method to your suspended caller. As mentioned, if the value being returned is crossing a thread, it'll be frozen. Run &lt;code&gt;returnDataCoroutine()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;returnDataCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🐶"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"result: $result, is frozen ${result.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;makeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sdIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello again 🐶"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sdIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result: SomeData(s=Hello again 🐶, i=122), is frozen true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When &lt;code&gt;makeData&lt;/code&gt; is called, the main thread suspends while &lt;code&gt;makeData&lt;/code&gt; runs in the background. When complete, the result is frozen, passed back to the caller and returned.&lt;/p&gt;

&lt;p&gt;As mentioned, multithreaded kotlinx.coroutines is in preview, which makes it's use in production apps somewhat restricted today. However, if you want to play with things a bit more, and see Flow in action, check out the &lt;code&gt;mt_coroutines&lt;/code&gt; branch from:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab" rel="noopener noreferrer"&gt;
        touchlab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab/DroidconKotlin" rel="noopener noreferrer"&gt;
        DroidconKotlin
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Kotlin Multiplatfom app for Droidcon Events
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  CoroutineWorker
&lt;/h2&gt;

&lt;p&gt;CoroutineWorker from Autodesk is a library intended to let you use coroutines in KN across threads with syntax and semantics similar to what you'll use when kotlinx.coroutines with multiple threads is live.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Autodesk" rel="noopener noreferrer"&gt;
        Autodesk
      &lt;/a&gt; / &lt;a href="https://github.com/Autodesk/coroutineworker" rel="noopener noreferrer"&gt;
        coroutineworker
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Kotlin Coroutine-based workers for native
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Once again, let's revert and switch branches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout .
git pull
git fetch
git checkout coroutine_worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You'll notice a very similar set of functions. In fact, everything we described above works basically the same. State captured is frozen, state returned is frozen. You call with &lt;code&gt;withContext&lt;/code&gt;, although the dispatcher you pass is only used on the jvm.&lt;/p&gt;

&lt;p&gt;Find &lt;code&gt;5) Coroutine Worker&lt;/code&gt; and run those methods in succession to verify they act the same.&lt;/p&gt;

&lt;p&gt;For example, run &lt;code&gt;captureStateCoroutine()&lt;/code&gt;. It is very similar to what we did with the MT coroutines preview, and behaves in a similar way.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureStateCoroutine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🥶"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(Coroutine) Am I frozen? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(Coroutine) Am I frozen now? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(Coroutine) Am I frozen? false
(Coroutine) Am I frozen now? true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We know of multiple teams using Coroutine Worker in production right now, and if the concurrency provided is sufficient, it's a great way to be source-ready for the full kotlinx.coroutines release.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reaktive
&lt;/h2&gt;

&lt;p&gt;Reaktive from Badoo is a reactive streams implementation for KMP, which includes KN support. If you are more of an RX fan vs Coroutines (if you get into that kind of debate), this is something you'll want to take a look at. We haven't done much since it was in preview, but will be taking a deeper look as part of our concurrency library review.&lt;/p&gt;

&lt;p&gt;Just FYI, there's currently no macos build for Reaktive, so our sample needs to be run through Xcode.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/badoo" rel="noopener noreferrer"&gt;
        badoo
      &lt;/a&gt; / &lt;a href="https://github.com/badoo/Reaktive" rel="noopener noreferrer"&gt;
        Reaktive
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Kotlin multi-platform implementation of Reactive Extensions
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Let's reset our sample again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout .
git pull
git fetch
git checkout reaktive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The code should look reasonably familiar to somebody with RxJava experience. Let's do a basic sample that loads data in an I/O thread and returns it to the UI.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;basicObservable&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;emitter&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"From io thread, is main thread? ${isMainThread}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;emitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"arst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribeOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observeOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mainScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;threadLocal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doOnBeforeNext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Callback is not frozen, we can updated the mutable list&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doOnBeforeFinally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;isFinished&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Callback is not frozen, we can change the flag&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"In main thread $isMainThread, is data frozen ${it.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We emit an instance of &lt;code&gt;SomeData&lt;/code&gt; in the I/O thread and it winds up in the &lt;code&gt;subscribe&lt;/code&gt; block. Data that chains through threads is frozen, as by now you'd probably expect.&lt;/p&gt;

&lt;p&gt;To see this in action, uncomment &lt;code&gt;basicObservable()&lt;/code&gt;, but to run it we need to do something different that before. Refresh gradle, and run the &lt;code&gt;build&lt;/code&gt; task. This will take some time to run. After that, open &lt;code&gt;iosApp/iosApp.xcworkspace&lt;/code&gt; in Xcode. Make sure it's &lt;code&gt;iosApp.xcworkspace&lt;/code&gt; and not &lt;code&gt;iosApp.xcodeproj&lt;/code&gt;. Once that is open, pick a simulator and run the project.&lt;/p&gt;

&lt;p&gt;You &lt;em&gt;should&lt;/em&gt; see the following output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;From io thread, is main thread? false
In main thread true, is data frozen true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Like with other libraries, you should be careful with state capture. Reaktive lives in the same state universe as everything else. Captured state will be frozen. Run &lt;code&gt;willFreeze()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;willFreeze&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"arst"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Frozen here? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;emitter&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"How about here? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;emitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribeOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observeOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mainScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;threadLocal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doOnBeforeNext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Callback is not frozen, we can updated the mutable list&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doOnBeforeFinally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;isFinished&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Callback is not frozen, we can change the flag&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Obviously frozen here? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On the output you'll see:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frozen here? false
How about here? true
Obviously frozen here? true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We're not going to go super deep on Reaktive in this post, but it's definitely an interesting project for concurrency.&lt;/p&gt;
&lt;h1&gt;
  
  
  What's next?
&lt;/h1&gt;

&lt;p&gt;This series is trying to avoid going too deep on the details and just explain enough for you to get started. If you want to go deeper and really understand what's happening, here are some other resources.&lt;/p&gt;

&lt;p&gt;I gave a talk this year at Kotlinconf. It covers a lot of the same content, but also goes into worker and some info on architectural thinking.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/oxQ6e1VeH4M"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Nikolay gave a talk at last year's Kotlinconf that goes into much deeper detail.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nw6YTfEyfO0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I wrote an earlier post series on the same topic. It is getting a bit old at this point, but it also explains deeper level topics.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/@kpgalligan/kotlin-native-stranger-threads-ep-1-1ccccdfe0c99" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afill%3A88%3A88%2F1%2AZVMJXu5ws0K0ldRsABTglQ.jpeg" alt="Kevin Galligan"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/@kpgalligan/kotlin-native-stranger-threads-ep-1-1ccccdfe0c99" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Kotlin Native Stranger Threads. Episode 1 — Worker | by Kevin Galligan | Medium&lt;/h2&gt;
      &lt;h3&gt;Kevin Galligan ・ &lt;time&gt;Jan 8, 2019&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fmedium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;Finally, the KN repo has some reference docs available. &lt;a href="https://github.com/JetBrains/kotlin-native/blob/master/CONCURRENCY.md" rel="noopener noreferrer"&gt;CONCURRENCY.md&lt;/a&gt; and &lt;a href="https://github.com/JetBrains/kotlin-native/blob/master/IMMUTABILITY.md" rel="noopener noreferrer"&gt;IMMUTABILITY.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As mentioned in Part 1, this series of docs is part of our KMP evaluation kit. The goal of the starter kit is to kickstart your team's KMP evaluation. You can sign up for access to that here: &lt;a href="https://go.touchlab.co/kampdevto" rel="noopener noreferrer"&gt;https://go.touchlab.co/kampdevto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Practical Kotlin Native Concurrency Part 2</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Mon, 16 Dec 2019 17:52:55 +0000</pubDate>
      <link>https://dev.to/touchlab/practical-kotlin-native-concurrency-part-2-48ac</link>
      <guid>https://dev.to/touchlab/practical-kotlin-native-concurrency-part-2-48ac</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/touchlab/practical-kotlin-native-concurrency-ac7"&gt;Back in part 1&lt;/a&gt;, you learned a bit about KN's state rules, installed and ran Intellij, and ran some sample code. In part 2 we'll dig a little deeper.&lt;/p&gt;

&lt;p&gt;First, update the sample! There may have been repo changes. Undo anything local and run &lt;code&gt;git pull&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout .
git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3) Global State
&lt;/h1&gt;

&lt;p&gt;Before we get into actual concurrent code, lets chat a bit about global state. Some things in Kotlin can be referenced globally, from any thread. As a result, KN treats them with special rules.&lt;/p&gt;

&lt;p&gt;These are kind of weird. However, there are only 2 types of global state, so just remember the weirdness.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;&lt;code&gt;object&lt;/code&gt; is frozen&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Any global &lt;code&gt;object&lt;/code&gt; is frozen, but that instance can be shared and referenced from any thread.&lt;/p&gt;

&lt;p&gt;Find &lt;code&gt;3) Global State&lt;/code&gt; in &lt;code&gt;SampleMacos.kt&lt;/code&gt; and uncomment &lt;code&gt;cantChangeThis()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;cantChangeThis&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i ${DefaultGlobalState.i}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;DefaultGlobalState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i ${DefaultGlobalState.i}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//We won't get here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;DefaultGlobalState&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will compile fine, but all global &lt;code&gt;object&lt;/code&gt; instances are frozen by default, so you'll see your old friend &lt;code&gt;InvalidMutabilityException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you need that state to be mutable you do have some options. You can use atomics, which we'll talk about later, but for now you can make that object thread local. That means each thread has it's own copy, and according to rule #1, mutable state == 1 thread.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;canChangeThreadLocal()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;canChangeThreadLocal&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i ${ThreadLocalGlobalState.i}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;ThreadLocalGlobalState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i ${ThreadLocalGlobalState.i}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ThreadLocal&lt;/span&gt;
&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;ThreadLocalGlobalState&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the annotation &lt;code&gt;@ThreadLocal&lt;/code&gt;. That tells the runtime that each thread has an instance defined. Running &lt;code&gt;canChangeThreadLocal()&lt;/code&gt; will print&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i 5
i 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that if you were accessing &lt;code&gt;ThreadLocalGlobalState&lt;/code&gt; from another thread, the value of &lt;code&gt;i&lt;/code&gt; would be different.&lt;/p&gt;

&lt;p&gt;Just an FYI. &lt;em&gt;These rules apply to companion objects as well&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;properties are main thread only&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;This is the "weird" rule. Global properties are neither thread local nor frozen. &lt;em&gt;They are only visible to the main thread&lt;/em&gt; &lt;sup id="fnref1"&gt;1&lt;/sup&gt;. This will seem odd, but just keep it in mind.&lt;/p&gt;

&lt;p&gt;To be clear, global &lt;em&gt;functions&lt;/em&gt; are fine. We're just talking about global &lt;em&gt;properties&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;globalCounting()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;globalCounting&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;globalCounterData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"count ${globalCounterData.i}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;globalCounterData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"count ${globalCounterData.i}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;globalCounterData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeMutableData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;count 34
count 35
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We haven't explained how to leave the main thread yet, but as a quick preview to demonstrate that properties are main thread only, run &lt;code&gt;globalCountingFail()&lt;/code&gt;. I won't show the code, but you'll get an exception:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread
        at 0   KNConcurrencySamples.kexe   (blah blah blah)
        at 1   KNConcurrencySamples.kexe   (blah blah blah)
(etc)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trying to access the top-level state fails&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;You can annotate top-level state with either &lt;code&gt;@ThreadLocal&lt;/code&gt;, which will give each thread a copy, or with &lt;code&gt;@SharedImmutable&lt;/code&gt;, which will make that state frozen and shared. We'll skip the code for that, though, and move on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Actual Concurrency
&lt;/h1&gt;

&lt;p&gt;We're going to leave the main thread now. In other explanations, I start by going deep on &lt;code&gt;Worker&lt;/code&gt;. &lt;code&gt;Worker&lt;/code&gt; is KN's primary concurrency primitive. It's a job queue that has it's own private thread.&lt;/p&gt;

&lt;p&gt;We won't be going over &lt;code&gt;Worker&lt;/code&gt;. Assuming you are using a library to manage concurrency, you won't interact with &lt;code&gt;Worker&lt;/code&gt; much, if at all. For a deeper understanding of what's happening, again I'd point you at my previous posts and talks, and if you're really curious, the JetBrains docs and videos go way into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emerging Model
&lt;/h2&gt;

&lt;p&gt;You can technically attempt to pass mutable state to other threads. In practice, KN concurrency libraries will freeze state when it goes between threads. This is true of the libraries we've been using internally, and the soon-to-be-released kotlinx.coroutines implementation.&lt;/p&gt;

&lt;p&gt;In this post we'll create a simple background thread processor. In a later post, we'll look at the kotlix.coroutines preview.&lt;/p&gt;

&lt;h2&gt;
  
  
  4) Background
&lt;/h2&gt;

&lt;p&gt;We've created a simple background task processor function to demonstrate crossing threads. The signature is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're not going to walk through that code because it uses worker and requires understanding a bit more complexity than we need.&lt;/p&gt;

&lt;p&gt;The important parts:&lt;/p&gt;

&lt;p&gt;1) The argument is a function, which will be executed in another thread&lt;br&gt;
2) That function argument itself will be frozen&lt;/p&gt;

&lt;p&gt;Here is a basic example. Run &lt;code&gt;basicBackground()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;basicBackground&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Is main thread $isMainThread"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Is main thread $isMainThread"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've also &lt;code&gt;isMainThread&lt;/code&gt;, which will require you're doing this on a Mac unless we get a PR that enables other platform. Anyway, the function prints the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is main thread true
Is main thread false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gets us onto another thread to do work, but obviously doesn't do much. This next example will pass some state into the other thread.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is very important to understand. If you were skimming the post, now is a good time to s l o w  d o w n.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;captureState()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureState&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🥶"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Am I frozen? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Am I frozen now? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will print:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Am I frozen? false
Am I frozen now? true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;It is very important to understand that function args can capture state, and when they are frozen, that state is also frozen.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As an alternate visualization, see below. When we call &lt;code&gt;background&lt;/code&gt;, that function argument is frozen, and since it captures &lt;code&gt;sd&lt;/code&gt;, which is a local val in the calling function, &lt;code&gt;sd&lt;/code&gt; is also frozen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2tznt8vinpj7spk8jwot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2tznt8vinpj7spk8jwot.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Local values are easy to understand and deal with. Where this becomes more problematic, and triggers more controversy, is when unintended state is captured.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;captureTooMuch()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We'll be using a more complex model class that has a number you can increment, and when you do, we push that value into a "database" in the background:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CountingModel&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
        &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="c1"&gt;//Do some db stuff&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our function to use the model looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureTooMuch&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CountingModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//We won't get here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's the result? Our old friend, &lt;code&gt;InvalidMutabilityException&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have 1
Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen sample.CountingModel@17e01008
        at 0   KNConcurrencySamples.kexe   (nah)
        at 1   KNConcurrencySamples.kexe   (meh)
(etc)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To help illustrate the issue here, consider &lt;code&gt;captureTooMuchAgain()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureTooMuchAgain&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CountingModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"model is frozen ${model.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"model is frozen ${model.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model is frozen false
model is frozen true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;count&lt;/code&gt; is an instance var of &lt;code&gt;CountingModel&lt;/code&gt;, so capturing &lt;code&gt;count&lt;/code&gt; in that way will capture the whole model and freeze it.&lt;/p&gt;

&lt;p&gt;To help avoid this, it is good practice to move thread-jumping code to another function, and only capture function arguments. Try &lt;code&gt;captureArgs()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureArgs&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CountingModelSafer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CountingModelSafer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
        &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;saveToDb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Doing db stuff with $arg, in main $isMainThread"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Debugging
&lt;/h2&gt;

&lt;p&gt;Going back to &lt;code&gt;captureTooMuch()&lt;/code&gt;, we get the &lt;code&gt;InvalidMutabilityException&lt;/code&gt; when we try to increment, but that's not super helpful. We want to know when/how our data got frozen in the first place. Obviously, in this example, it's not hard to track down, but in more complex examples it will be.&lt;/p&gt;

&lt;p&gt;You can mark an object that should never be frozen with &lt;code&gt;ensureNeverFrozen()&lt;/code&gt;. When freeze is happening, the runtime will throw an exception at the point of freezing. Run &lt;code&gt;captureTooMuchSource()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureTooMuchSource&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CountingModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ensureNeverFrozen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I have ${model.count}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//We won't even get here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will get us an exception that traces right back to the root issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uncaught Kotlin exception: kotlin.native.concurrent.FreezingException: freezing of sample.CountingModel.$increment$lambda-0$FUNCTION_REFERENCE$2@7d601058 has failed, first blocker is sample.CountingModel@7d601008
        at 0   KNConcurrencySamples.kexe   (ugh)
        at 1   KNConcurrencySamples.kexe   (stuff)
(skip a few lines...)
        at 13  KNConcurrencySamples.kexe           0x00000001088c570d kfun:sample.background(kotlin.Function0&amp;lt;kotlin.Unit&amp;gt;) + 301 (/Users/kgalligan/temp/KNConcurrencySamples/src/macosMain/kotlin/sample/BackgroundSupport.kt:12:12)
        at 14  KNConcurrencySamples.kexe           0x00000001088c5102 kfun:sample.CountingModel.increment() + 258 (/Users/kgalligan/temp/KNConcurrencySamples/src/macosMain/kotlin/sample/Background.kt:35:9)
        at 15  KNConcurrencySamples.kexe           0x00000001088c547e kfun:sample.captureTooMuchSource() + 286 (/Users/kgalligan/temp/KNConcurrencySamples/src/macosMain/kotlin/sample/Background.kt:77:11)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stack trace is a bit verbose, but you'll be able to walk back to the source issue.&lt;/p&gt;

&lt;h1&gt;
  
  
  End
&lt;/h1&gt;

&lt;p&gt;That's a wrap for Part 2. In Part 3 we'll wrap up the primitives with atomics, then introduce various libraries you can use for concurrency in you applications.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I don't know for sure why they made that decision. However, I suspect it's because you can get into trouble. Early on, global vals were thread-local. If you create a Worker as a global, it'll start a new thread. That thread gets it's own Worker, which starts a new thread. Etc. Good times. KN no longer does this. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Sort of? Apparently, simple integer data at least can be shared and mutable. Run &lt;code&gt;globalCountingTil()&lt;/code&gt;. You'll need to add that method manually to main. It lets you edit a global &lt;code&gt;Int&lt;/code&gt;. Not sure how why, but investigating. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Practical Kotlin Native Concurrency</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Mon, 16 Dec 2019 17:51:17 +0000</pubDate>
      <link>https://dev.to/touchlab/practical-kotlin-native-concurrency-ac7</link>
      <guid>https://dev.to/touchlab/practical-kotlin-native-concurrency-ac7</guid>
      <description>&lt;p&gt;One of the more confusing things about Kotlin Native (henceforth 'KN') for new developers is the state and concurrency model. In general, Kotlin developers come from the JVM, and expect everything to be the same. It is not.&lt;/p&gt;

&lt;p&gt;However, although different, the model is conceptually simple. With practice, getting your head around it is not too difficult.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post series is part of the KMP Starter Kit available here: &lt;a href="https://go.touchlab.co/kampdevto"&gt;https://go.touchlab.co/kampdevto&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;Languages like Java, C++, Swift/Objc, let multiple threads access the same state in an unrestricted fashion. It is up to you, the developer, to avoid doing bad things. Concurrency issues are unlike other programming issues in that they are often very difficult to reproduce. You won't see them locally, but in production, at load, they emerge.&lt;/p&gt;

&lt;p&gt;Just because your tests pass does not mean your code is OK.&lt;/p&gt;

&lt;p&gt;Not all languages are designed this way. Most familiar to developers would be Javascript. You can achieve some level of concurrency with &lt;code&gt;Worker&lt;/code&gt;, but you can't reference and modify the same state at the same time. The language Rust is built for performance and safety. Concurrency management is designed into the language, so it is essentially like C++ minus the inherent risk of unrestricted shared state &lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;KN has rules around how state is shared between threads. These rules exist for KN but not Kotlin JVM (henceforth KJ). However, a critical goal of Kotlin Multiplatform is that the various versions of Kotlin remain source-compatible. Changing the language itself to enforce concurrency (like Rust), while in some ways appealing, would break support for JS and JVM. Thus, the new rules for KN are implemented and enforced in the runtime.&lt;/p&gt;

&lt;h1&gt;
  
  
  Two Rules
&lt;/h1&gt;

&lt;p&gt;The new rules are conceptually simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Mutable state == 1 thread
&lt;/h2&gt;

&lt;p&gt;If your state is mutable, only one thread can "see" it at a time. We'll explain what that means later, but assume all state is "mutable", and if you aren't doing any concurrency, KN will feel pretty much the same as anything else you've written in Kotlin (except if you use a top-level property or companion &lt;code&gt;object&lt;/code&gt;. See "Global State" in Part 2 for detail).&lt;/p&gt;

&lt;p&gt;The goal of rule 1 is simple. If there's only 1 thread, you don't have concurrency issues. Technically this is referred to as "thread confinement". For native mobile and desktop UI developers, this should be familiar. You cannot change the UI from a background thread. KN has generalized that concept.&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Immutable state == many threads
&lt;/h2&gt;

&lt;p&gt;If state can't be changed, it can be shared between threads. This is also conceptually simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it. Two rules.
&lt;/h2&gt;

&lt;p&gt;How that is implemented, and the implications, are obviously more involved, but the basic concepts underlying KN and concurrency are very simple.&lt;/p&gt;

&lt;h1&gt;
  
  
  Status
&lt;/h1&gt;

&lt;p&gt;Just a quick sidebar on the status of KN and it's concurrency rules. The community has been growing over the past few years, and there is pressure to relax these rules to make the transition from KJ easier. That &lt;em&gt;may&lt;/em&gt; continue over time, but not in a breaking way. That means, it's &lt;em&gt;possible&lt;/em&gt; these rules will be relaxed a bit in 2020, but code written now will work. There is also pressure to keep these rules, and simply improve the onboarding experience. You could say I'm in that camp, hence this post. Anyway...&lt;/p&gt;

&lt;h1&gt;
  
  
  Code!!!
&lt;/h1&gt;

&lt;p&gt;First, get the sample. To use the sample you'll need &lt;a href="https://www.jetbrains.com/idea/download/#section=mac"&gt;Intellij Community (or Ultimate) 2019.3&lt;/a&gt; or higher.&lt;/p&gt;

&lt;p&gt;Clone the sample repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/touchlab"&gt;
        touchlab
      &lt;/a&gt; / &lt;a href="https://github.com/touchlab/KNConcurrencySamples"&gt;
        KNConcurrencySamples
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Once cloned, open the sample project in Intellij.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Simple State
&lt;/h2&gt;

&lt;p&gt;First we'll start with some basic state. Basic vars, mutating values. Not super interesting. Just showing how things work when you're not doing any concurrency.&lt;/p&gt;

&lt;p&gt;Open the sample project in Intellij. Find &lt;code&gt;SampleMacos.kt&lt;/code&gt;. In the main function there will be code that is commented out. Look for &lt;code&gt;1) Simple State&lt;/code&gt; and uncomment &lt;code&gt;runSimpleState()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Over on the right of the IDE, find "Gradle", then in that window, find &lt;code&gt;runDebugExecutableMacos&lt;/code&gt; and double-click.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DZHhpZoR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oia0jfisuza11ymo8q0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZHhpZoR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oia0jfisuza11ymo8q0k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a very basic sample. It is demonstrating that state which is in a single thread is mutable as usual.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;runSimpleState&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SimpleState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleState&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;count--&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My count $count"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will print:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My count 2
My count 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Moving on...&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Frozen State
&lt;/h2&gt;

&lt;p&gt;All state is mutable unless it is frozen. Frozen state is a new concept for Kotlin, although it exists in some other languages. In KN, there is a function &lt;code&gt;freeze()&lt;/code&gt; defined on all classes. When you call &lt;code&gt;freeze()&lt;/code&gt;, that object and everything it touches is frozen and immutable.&lt;/p&gt;

&lt;p&gt;Once frozen, state can be shared between threads, but it cannot be changed.&lt;/p&gt;

&lt;p&gt;Look for "2) Frozen State" in the &lt;code&gt;SampleMacos.kt&lt;/code&gt;. Uncomment &lt;code&gt;freezeSomeState()&lt;/code&gt; and run it (by "run it" from now on I mean run &lt;code&gt;runDebugExecutableMacos&lt;/code&gt; again).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;freezeSomeState&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello 🐶"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Am I frozen? ${sd.isFrozen}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;SomeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Am I frozen? true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Understand that your state is being changed at runtime. There is a flag on every object in KN that says if it is frozen or not, and for &lt;code&gt;sd&lt;/code&gt; we have just flipped it to true.&lt;/p&gt;

&lt;p&gt;Back in &lt;code&gt;SampleMacos.kt&lt;/code&gt;, comment out any other uncommented method, and uncomment &lt;code&gt;failChanges()&lt;/code&gt;. Run again.&lt;/p&gt;

&lt;p&gt;This will fail with an exception. The output console in Intellij can be a little confusing to navigate. Make sure you click the top level to see the full output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V8aTLgSd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qvqf4sbxb2uhhm7btpp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V8aTLgSd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qvqf4sbxb2uhhm7btpp9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;failChanges&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;smd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SomeMutableData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;smd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"smd: $smd"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;smd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;smd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"smd: $smd"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//We won't actually get here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;SomeMutableData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The output looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;smd: SomeMutableData(i=4)
Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen sample.SomeMutableData@8b40c4b8
        at 0   KNConcurrencySamples.kexe  (yada yada)
        at 1   KNConcurrencySamples.kexe  (yada yada)
(etc)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The important points. Before we freeze the object, you can change the &lt;code&gt;var&lt;/code&gt; value. After we freeze, if you try to change the value, it'll throw an exception. &lt;code&gt;InvalidMutabilityException&lt;/code&gt;, to be precise.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;InvalidMutabilityException&lt;/code&gt; is your new friend. You will probably not feel that way at first, but it is.&lt;/p&gt;

&lt;p&gt;When you see &lt;code&gt;InvalidMutabilityException&lt;/code&gt;, it means you are attempting to change some state that has been frozen. You probably did not want this state to be frozen, so your job will be to figure out why it was frozen. Remember, when you freeze something, everything it touches is frozen. We'll talk about this in detail later. All I can say from experience is, at first this will be somewhat confusing. Pretty soon it won't be. Just understand the system and the tools you can use to debug.&lt;/p&gt;

&lt;h1&gt;
  
  
  End
&lt;/h1&gt;

&lt;p&gt;That's it for part one. We have installed the IDE, and run some basic sample functions. We have not written any concurrent code yet. Step one is simply understanding the basics.&lt;/p&gt;

&lt;p&gt;These posts are intended to be a functional intro to concurrency on KN. We're going to skip over a lot and just present what you're likely to use day to day. If you'd like a deeper dive, check out &lt;a href="https://medium.com/@kpgalligan/kotlin-native-stranger-threads-ep-1-1ccccdfe0c99"&gt;Stranger Threads&lt;/a&gt; and my &lt;a href="https://twitter.com/kpgalligan/status/1202821639278399488?s=20"&gt;Kotlinconf talk&lt;/a&gt;.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Yes, I'm sure Rust is other things too, but in &lt;em&gt;this&lt;/em&gt; context... ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Kotlin Native iOS Crash Reporting</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Tue, 26 Nov 2019 23:54:58 +0000</pubDate>
      <link>https://dev.to/touchlab/kotlin-native-ios-crash-reporting-3m84</link>
      <guid>https://dev.to/touchlab/kotlin-native-ios-crash-reporting-3m84</guid>
      <description>&lt;p&gt;Crash reporting tools are critical to the success of any mobile product. Knowing when things fail, and how, is information you need to make sure things are running smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Kotlin code running on iOS has an issue specific to the design differences between the JVM and iOS. The JVM and Kotlin rely on exceptions, while iOS really does not.&lt;/p&gt;

&lt;p&gt;When a crash happens on Android in the JVM, an exception will bubble up until something catches it. If it makes its way to the default exception handler, the app generally "crashes", with maybe a report to a crash reporting library.&lt;/p&gt;

&lt;p&gt;On iOS, without exception propagation, the system simply "crashes". The crash reporting tool will capture the state of the threads at that moment.&lt;/p&gt;

&lt;p&gt;For Kotlin, this introduces a problem. To stay consistent with Kotlin on the JVM, exceptions propagate in the same way on iOS. At the border between Swift/Objc and Kotlin, uncaught exceptions will trigger a crash. Because of how iOS crashes work, that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvs7xv4rergx5of8v085o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvs7xv4rergx5of8v085o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They all end with &lt;code&gt;konan::abort()&lt;/code&gt;, which internally force-kills the app. For crash reporting, that isn't super useful.&lt;/p&gt;

&lt;p&gt;You can add the stack trace in the crash report log as a string, but you may lose detail, and in any case, the errors won't be grouped by the stack trace.&lt;/p&gt;

&lt;p&gt;Kotlin 1.3.60 introduces crash data being written to the iOS internal crash log and better symbolication support. You can get the crash data from the local device, if you have access to it, or Apple's developer site, but neither is ideal in many cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing CrashKiOS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/touchlab/CrashKiOS" rel="noopener noreferrer"&gt;CrashKiOS&lt;/a&gt; (Crash reporting for Kotlin iOS) is a simple library that let's you send symbolicated crash reports to crash reporting systems like Crashlytics and Bugsnag. It leverages the crash data improvements in Kotlin 1.3.60, and uses the existing crash reporting API's.&lt;/p&gt;

&lt;p&gt;The end result is crash reports that look more like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkiwbpwi58oepzjo0mwkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkiwbpwi58oepzjo0mwkf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find setup and config details in the &lt;a href="https://github.com/touchlab/CrashKiOS" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it Works
&lt;/h2&gt;

&lt;p&gt;Conceptually, the way it works is we add a default exception handler to the Kotlin code, which will be triggered if an exception winds its way to the interface between Kotlin and Swift/Objc.&lt;/p&gt;

&lt;p&gt;We define an open class that gets called from that default exception handler. That class is extended in Swift (or Objc), and the report is sent to the crash reporting system.&lt;/p&gt;

&lt;p&gt;There are two basic options. Get the raw Throwable, or get the parts of the crash necessary to be sent to the crash reporting tool.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;crash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;crashParts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;exceptionType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In our current implementations, reports are all "handled errors", as there is no published way to send a custom fatal crash, but we'll be looking into ways to do that in the future.&lt;/p&gt;

&lt;p&gt;For both Crashlytics and Bugsnag, rather than provide the stack trace as a string, we supply the code addresses, which are translated back to the source code lines by way of dsym files. For Crashlytics, that looks like the following.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;CrashlyticsCrashHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CrashkiosCrashHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;crashParts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;KotlinLong&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="nv"&gt;exceptionType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;clsStackTrace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;addresses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;CLSStackFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;truncating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;Crashlytics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sharedInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recordCustomExceptionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;exceptionType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nv"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nv"&gt;frameArray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clsStackTrace&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;clsStackTrace&lt;/code&gt; is a stack trace built from the code addresses. Both Crashlytics and Bugsnag can take that info and produce a stack trace. Presumably other crash reporting tools would work the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just FYI
&lt;/h2&gt;

&lt;p&gt;The last couple stack lines are generally boilerplate exception initialization, which we strip out (the screenshot above was from an earlier version where those lines were left in). That logic may need more tweaking over time.&lt;/p&gt;

&lt;p&gt;Currently, Kotlin debug builds give line numbers while release builds only provide function names. Hopefully we'll have better config for that after some more research.&lt;/p&gt;

&lt;p&gt;We'll be making improvements over time as we learn more about how iOS deals with crash reports and how to better integrate with vaious crash reporting systems. If you'd like to add a different system, or have some ideas about how to improve support, please reach out (&lt;a class="mentioned-user" href="https://dev.to/kpgalligan"&gt;@kpgalligan&lt;/a&gt; on twitter, or find me in the Kotlin Slack).&lt;/p&gt;

&lt;h2&gt;
  
  
  Touchlab KMP Stuff!
&lt;/h2&gt;

&lt;p&gt;Touchlab is publishing a Kotlin Multiplatform evaluation kit for orgs interested in the tech, called the KaMP Kit. You can get access by going to our &lt;a href="https://go.touchlab.co/KaMP-Kit" rel="noopener noreferrer"&gt;signup form&lt;/a&gt;. Also, we're hiring mobile developers, in particular people experienced in or at least interested in multiplatform tech. See our &lt;a href="https://go.touchlab.co/kmpdevs" rel="noopener noreferrer"&gt;careers page&lt;/a&gt; for more info.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Kotlin Native Coroutines Preview</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Fri, 15 Nov 2019 18:42:37 +0000</pubDate>
      <link>https://dev.to/touchlab/kotlin-native-coroutines-preview-3edc</link>
      <guid>https://dev.to/touchlab/kotlin-native-coroutines-preview-3edc</guid>
      <description>

&lt;p&gt;Very recently, a &lt;a href="https://github.com/Kotlin/kotlinx.coroutines/pull/1648" rel="noopener noreferrer"&gt;draft PR (#1648)&lt;/a&gt; landed in the &lt;a href="https://github.com/Kotlin/kotlinx.coroutines" rel="noopener noreferrer"&gt;kotlinx.coroutines github&lt;/a&gt; that will enable multithreaded coroutines in Kotlin Native (KN). &lt;em&gt;This is a big deal for the technology, and a lot of people have been waiting for it&lt;/em&gt;. I tweeted a little screenshot, and just that got a fair bit of attention&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1195083478825684992-99" src="https://platform.twitter.com/embed/Tweet.html?id=1195083478825684992"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1195083478825684992-99');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1195083478825684992&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;It is not a stretch to say a lot of developers have been waiting for this, as one of the tweet replies highlights:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1195376410522738688-361" src="https://platform.twitter.com/embed/Tweet.html?id=1195376410522738688"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1195376410522738688-361');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1195376410522738688&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;To be clear, as much as this is a good thing technically, I think it's a big deal psychologically. You could achieve concurrency before multithreaded coroutines, and there are certain to be issues as the implementation emerges. However, a lot of people were waiting for this. There are technical reasons people were waiting, but in a more general sense, it's a reality signal. &lt;em&gt;Multithreaded Coroutines make Kotlin Native more "real"&lt;/em&gt;. In the JVM world, coroutines have been dominating the conversation around concurrency, so the lack of "full" coroutines in native was a signal that it's wasn't ready, or not a priority. That is changing.&lt;/p&gt;

&lt;p&gt;What does this mean? In short, a big block to adoption has been removed. There's a lot of library work around architecture and concurrency that hasn't been happening because those implementations would largely be obsolete once multithreaded coroutines emerged. That block has been removed. &lt;em&gt;We should expect a lot of follow-on library work, tech talks, and blog posts. Shortly after that, a lot of production deployment&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In short, a big block to adoption has been removed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There has also been uncertainty around the threading model. Going back to the summer, the Kotlin Native repo got an experimental addition. &lt;a href="https://github.com/JetBrains/kotlin-native/pull/3129" rel="noopener noreferrer"&gt;Relaxed mode&lt;/a&gt;. It essentially let you access shared memory just like you can in the JVM. Whether that is a good thing or not is a much longer debate (&lt;a href="https://kotlinconf.com/talks/5-dec/127136/" rel="noopener noreferrer"&gt;which I'll be talking about at Kotlinconf&lt;/a&gt;). However, a lot of the community assumed relaxed mode existed in preparation for multithreaded coroutines. If relaxed mode became popular, it would probably end strict mode, but it was unclear which way things would go. There was a lot of uncertainty.&lt;/p&gt;

&lt;p&gt;The uncertainty around Kotlin Native's state model is gone. Multithreaded coroutines work within the strict state model of Kotlin Native. That means although relaxed mode may be supported in the future, it is not the primary direction of the platform. Strict mode is here to stay.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The uncertainty around Kotlin Native's state model is gone.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are currently in the middle of November. PR #1648 is still working it's way through completion. I would assume there is some release by Kotlinconf, which is ~3 weeks away. Just in time for people taking holidays to poke around. I'd expect to see a bit of activity in the community before the new year.&lt;/p&gt;

&lt;p&gt;We will be doing an update to the &lt;a href="https://github.com/touchlab/DroidconKotlin/" rel="noopener noreferrer"&gt;DroidconKotlin app&lt;/a&gt;, using a few new libraries and, of course, multithreaded coroutines. Hopefully, we'll have a version of that out before Droidcon SF, but if not, sometime in December.&lt;/p&gt;

&lt;p&gt;This is also a good time to tell you about our &lt;a href="https://go.touchlab.co/KaMP-BL" rel="noopener noreferrer"&gt;KaMP Kit&lt;/a&gt;. We've been talking to orgs evaluating Kotlin Multiplatform who have had some trouble getting started. The platform is moving fast, and there's a lot of conflicting or outdated info out there on the web. The KaMP Kit is a set of starter repos and documentation to get you set up for success quickly. Our first version will be released in mid-December. &lt;a href="https://go.touchlab.co/KaMP-BL" rel="noopener noreferrer"&gt;Go here&lt;/a&gt; to sign up for early access.&lt;/p&gt;




&lt;p&gt;Touchlab is hiring mobile engineers excited about Kotlin Multiplatform. We are a remote friendly org. &lt;a href="https://go.touchlab.co/971" rel="noopener noreferrer"&gt;Come check that out&lt;/a&gt; if interested.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Debugging Kotlin Native’s Compiler</title>
      <dc:creator>Kevin Galligan</dc:creator>
      <pubDate>Sun, 26 May 2019 20:22:49 +0000</pubDate>
      <link>https://dev.to/touchlab/debugging-kotlin-native-s-compiler-3afb</link>
      <guid>https://dev.to/touchlab/debugging-kotlin-native-s-compiler-3afb</guid>
      <description>&lt;p&gt;In order to add &lt;a href="https://github.com/JetBrains/kotlin-native/pull/2850"&gt;generics to header output&lt;/a&gt; in Kotlin Native, I had to kind of reverse engineer the Kotlin native compiler using a debugger 👎. Attaching a debugger to the Konan compiler requires a few steps, but is relatively straightforward.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Build Kotlin Native
&lt;/h1&gt;

&lt;p&gt;You’ll need to &lt;a href="https://github.com/JetBrains/kotlin-native/"&gt;clone KN&lt;/a&gt; and make sure to create a branch pointing at the version you want to use. As the docs state, this will take at least an hour, and in my experience, that’s optimistic, but it’s generally a trouble free build. Just take a walk/nap.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create Sample Project
&lt;/h1&gt;

&lt;p&gt;When you run into a compile issue, it may be in the context of a much larger application. While you could directly debug on that, I’d suggest making a minimal sample that surfaces the same issue. It’ll save you time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Config Sample Project
&lt;/h1&gt;

&lt;p&gt;You need to point the sample project at your local Konan build, and tell the compiler you want to attach a debugger. Add the following to your gradle.properties:&lt;/p&gt;

&lt;p&gt;org.jetbrains.kotlin.native.home=[Koltin Native Clone Dir]/dist&lt;br&gt;
org.jetbrains.kotlin.native.jvmArgs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5006&lt;br&gt;
Replace [Kotlin Native Clone Dir] with whatever dir you built KN in. That will tell the kotlin plugin to use that instead of the regular compiler and runtime. The second line makes the konan compiler wait for a remote debugger to connect.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Config Remote Debugger (the easy part)
&lt;/h1&gt;

&lt;p&gt;Open the Kotlin Native repo in Intellij (it’s a gradle project). Once that’s open, create a remote debugger config.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit Configurations
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w9pxdhAP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0nw6fsrp32wx3x4mf60w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w9pxdhAP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0nw6fsrp32wx3x4mf60w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add ‘Remote’
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4Hmr4Cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4in5xtodlsh7dzxl71hk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4Hmr4Cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4in5xtodlsh7dzxl71hk.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Port to 5006
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CGYorVv5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7vkervncynj5pupwnu3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CGYorVv5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7vkervncynj5pupwnu3u.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look back to step 3, we set the port to 5006&lt;/p&gt;

&lt;p&gt;org.jetbrains.kotlin.native.jvmArgs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5006&lt;br&gt;
Make sure that’s set in your Remote config.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Profit
&lt;/h1&gt;

&lt;p&gt;Now go back to your test project and build it. I generally do that on the command line with ./gradlew build. You’ll get a message telling you to attach a debugger.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4PhS5_eT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4s2q18g9fuxosxp90xfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4PhS5_eT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4s2q18g9fuxosxp90xfm.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to the Kotlin Native Intellij project and run the Remote config. It’ll attach and let the compiler run.&lt;/p&gt;

&lt;p&gt;In my testing, I actually needed to debug a different task, so I’d need to attach the debugger twice. I’d see this back in the sample project…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JoNPr02Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0zr8ezwvgeuxa5anlrra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JoNPr02Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0zr8ezwvgeuxa5anlrra.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, while a little clunky, just attach again.&lt;/p&gt;

&lt;p&gt;Also, don’t forget to add breakpoints in the compiler code, which is the point.&lt;/p&gt;

&lt;p&gt;Running the test app and debugger together in a video (sorry about audio. Will redo with a real mic if there’s interest)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=6W00Ngx0ESw"&gt;Debug Video&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;👎 There is some anti-debugger feelings out there in TDD land, but the idea that debuggers are bad practice completely ignores the discovery use case, which is huge. This is a fantastic example of that. I really dislike the “real developers don’t use debuggers” attitude. Just ranting a bit about that here. Anyway…&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotlinnative</category>
      <category>kotlinmultiplatform</category>
    </item>
  </channel>
</rss>
