All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.aws.smithy.kotlin.runtime.util.LazyAsyncValue.kt Maven / Gradle / Ivy

There is a newer version: 0.15.0
Show newest version
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

package aws.smithy.kotlin.runtime.util

import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

/**
 * A value that is produced asynchronously and cached after first initialized.
 *
 * Similar to `Lazy` but supports asynchronous initialization. Implementations
 * MUST be thread safe.
 *
 * NOTE: Properties cannot be loaded asynchronously so unlike `Lazy` a `LazyAsyncValue` cannot be a property
 * delegate.
 */
interface LazyAsyncValue {
    /**
     * Get the cached value or initialize it for the first time. Subsequent calls will return the same value.
     */
    suspend fun get(): T
}

/**
 * Create a [LazyAsyncValue] with the given [initializer]
 */
public fun  asyncLazy(initializer: suspend () -> T): LazyAsyncValue = LazyAsyncValueImpl(initializer)

internal object UNINITIALIZED_VALUE

/**
 * A value that is initialized asynchronously and cached after it is initialized. Loading/access is thread safe.
 */
private class LazyAsyncValueImpl (initializer: suspend () -> T) : LazyAsyncValue {
    private val mu = Mutex()
    private var initializer: (suspend () -> T)? = initializer
    private var value: Any? = UNINITIALIZED_VALUE

    override suspend fun get(): T = mu.withLock {
        if (value === UNINITIALIZED_VALUE) {
            value = initializer!!()
            initializer = null
        }
        @Suppress("UNCHECKED_CAST")
        return value as T
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy