# Request: structured resource management kotlin library

**URL:** <https://discuss.kotlinlang.org/t/request-structured-resource-management-kotlin-library/24629>\
**Category:** Language Design\
**Created:** [April 15, 2022, 3:48pm UTC](https://discuss.kotlinlang.org/t/request-structured-resource-management-kotlin-library/24629 "2022-04-15T15:48:19Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![franztesca](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@franztesca](https://discuss.kotlinlang.org/u/franztesca)\
**Post date:** [April 15, 2022, 3:48pm UTC](https://discuss.kotlinlang.org/t/request-structured-resource-management-kotlin-library/24629/1 "2022-04-15T15:48:20Z")

</div>

IMHO one of the limitations of Java is resource management: garbage collections works well enough when it comes to Java objects, but sometimes some native resources are referenced and are not garbage collected, or they are garbage collected only at a later stage but the developer wants to to promptly release then.  
The java solution? `Closeable`, `AutoCloseable`.  
Well, they work decently but they have some clear limitation:

- They introduce an additional method to the interface.
- Every object owning a `Closeable` resource must be `Closeable` itself if it doesn’t consume the resource. (for example, `InputStreamReader` is `Closeable`).
- The resource can easily leak in different scenarios, for example during the transfer of the object reference to its owner:

```kotlin
class MyClass: Closeable {
    private val file1 = FileInputStream()
    private val file2 = FileInputStream() // If this fails then file1 is leaked

    override fun close() {
        file1.close()
        file2.close() // This is never executed if file1.close fails
    }    
}

```

- One particular use case where they can easily leak without being notice is with coroutines. The following code looks safe, but it is not really. If the coroutine is cancelled during the `withContext` execution, the `FileInputStream` is leaked.

```kotlin
suspend fun fileInputStream() = withContext(Dispatchers.IO) {
    FileInputStream()
}

fun user() {
    fileInputStream().use {
        // do something
    }
}

```

This issue doesn’t have a real resolution: [Universal API for use of closeable resources with coroutines · Issue #1191 · Kotlin/kotlinx.coroutines · GitHub](https://github.com/Kotlin/kotlinx.coroutines/issues/1191)

In general, `Closeable` works, but has some important limitations and makes the code prone to resource-leakage, bloated of close methods and with more compromises (a `ByteArrayInputStream` must implement `close` with NOOP).

The solution? It’s already present in the KEEP of context receivers: [KEEP/context-receivers.md at master · Kotlin/KEEP · GitHub](https://github.com/Kotlin/KEEP/blob/master/proposals/context-receivers.md#use-cases)

```kotlin
interface AutoCloseScope {
    fun defer(closeBlock: () -> Unit)
}

context(AutoCloseScope)
fun File.open(): InputStream

fun withAutoClose(block: context(AutoCloseScope) () -> Unit) {
    val scope = AutoCloseScopeImpl() // Not shown here
    try {
        with(scope) { block() }
    } finally {
        scope.close()
    }   
}

// usage
withAutoClose {
    val input = File("input.txt").open()
    val config = File("config.txt").open()
    // Work
    // All files are closed at the end
}

```

Structured resources. Just like what coroutines did for concurrency, a new library can do for resource management.  
This would move the resource registration from the interface of the object to the implementation:

```auto
interface MyInputStream {
    fun read(): Int
   // It doesn't have a close method or inherit from Closeable
}

class MyByteArrayInputStream: MyInputStream {
    override fun read()
    // No need for noop close
}

class MyInputStreamReader(
    private val inputStream: MyInputStream
) {
  // no close method, no Closeable interface
}

fun usage() {
    val reader = MyInputStreamReader(MyByteArrayInputStream())
    // no need to close anything :D 
}

context(AutoCloseScope)
class MyFileInputStream: MyInputStream {
    init {
        defer { closeMyFile() }
    }
}

fun usage2() {
    withAutoClose {
        val stream = MyFileInputStream()
    }
    // This is disallowed, it wont compile without an AutoCloseScope context
    // val stream = MyFileInputStream()
}

```

This solution solves many of the problems:

- No additional close method is needed on the interface.
- Objects that are not owning the resource don’t have to be `Closeable` (such as `InputStreamReader`)
- It makes resource leaking much more difficult

```kotlin
context(AutoCloseScope)
class MyClass {
    private val file1 = MyFileInputStream()
    private val file2 = MyFileInputStream() // If this fails then file1 is NOT leaked
}
// release cannot leak as well

```

- It works well with coroutines

```kotlin
context(AutoCloseScope)
suspend fun fileInputStream() = withContext(Dispatchers.IO) {
    MyFileInputStream()
}

// This is now safe and don't leak even during cancellation
suspend fun user() {
    withAutoClose {
        fileInputStream()
        // do stuff
    }
}

```

What is missing?  
A more advanced solution that supports all the use cases, has a clear API and widely used.  
Interoperability of different custom implementations of AutoCloseScope would be messy.  
What I am suggesting with this post is an investigation around this possibilities and what it can potentially enable. Structured resource management could be a nice addition to the kotlin libraries and could tackle both the limitations of `Closeable` and the kotlin-specific problems related to coroutines.

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [April 18, 2022, 4:06pm UTC](https://discuss.kotlinlang.org/t/request-structured-resource-management-kotlin-library/24629/2 "2022-04-18T16:06:27Z")

</div>

Managing resources without leakage is a challenging issue. In particular when it involves other abstractions. It is easy enough to use/overload the `use` function, but it still allows iterators to be leaked. An `AutoCloseScope` can enhance this, but the way I’m currently leaning is to go the monad way. Meaning that the resource usage will be evaluated directly with its creation, therefore stopping any leakage (of course stale iterator are still possible if you’re being silly about things).
