alibaba/transmittable-thread-local

View on GitHub
ttl-kotlin/src/main/kotlin/com/alibaba/ttl3/kotlin/TtlExtensions.kt

Summary

Maintainability
D
2 days
Test Coverage
package com.alibaba.ttl3.kotlin

import com.alibaba.ttl3.TtlCallable
import com.alibaba.ttl3.TtlRunnable
import com.alibaba.ttl3.TtlWrappers
import com.alibaba.ttl3.executor.TtlExecutors
import com.alibaba.ttl3.spi.TtlEnhanced
import com.alibaba.ttl3.spi.TtlWrapper
import com.alibaba.ttl3.transmitter.Transmitter
import java.util.concurrent.*
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory
import java.util.function.*
import java.util.function.Function


////////////////////////////////////////
// Runnable
////////////////////////////////////////

/**
 * wrap input [Runnable] to [TtlRunnable].
 *
 * @see TtlRunnable.get
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Runnable.ttlWrap(
    releaseTtlValueReferenceAfterRun: Boolean = false,
    idempotent: Boolean = false
): TtlRunnable = TtlRunnable.get(this, releaseTtlValueReferenceAfterRun, idempotent) as TtlRunnable

/**
 * unwrap [TtlRunnable] to the original/underneath one.
 *
 * @see TtlRunnable.ttlUnwrap
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Runnable.ttlUnwrap(): Runnable = TtlRunnable.unwrap(this) as Runnable

/**
 * wrap input [Runnable] collection to [TtlRunnable] collection.
 *
 * @see TtlRunnable.gets
 */
@JvmName("ttlWrapRunnableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun Collection<Runnable>?.ttlWrap(
    releaseTtlValueReferenceAfterRun: Boolean = false,
    idempotent: Boolean = false
): List<TtlRunnable> = TtlRunnable.gets(this, releaseTtlValueReferenceAfterRun, idempotent)

/**
 * wrap input nullable [Runnable] collection to [TtlRunnable] collection.
 *
 * @see TtlRunnable.gets
 */
@JvmName("ttlWrapNullableRunnableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun Collection<Runnable?>?.ttlWrap(
    releaseTtlValueReferenceAfterRun: Boolean = false,
    idempotent: Boolean = false
): List<TtlRunnable?> = TtlRunnable.gets(this, releaseTtlValueReferenceAfterRun, idempotent)

/**
 * unwrap [TtlRunnable] to the original/underneath one for collection.
 *
 * @see TtlRunnable.unwraps
 */
@JvmName("ttlUnwrapRunnableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun Collection<Runnable>?.ttlUnwrap(): List<Runnable> =
    TtlRunnable.unwraps(this)

/**
 * unwrap nullable [TtlRunnable] to the original/underneath one for collection.
 *
 * @see TtlRunnable.unwraps
 */
@JvmName("ttlUnwrapNullableRunnableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun Collection<Runnable?>?.ttlUnwrap(): List<Runnable?> =
    TtlRunnable.unwraps(this)


////////////////////////////////////////
// Callable
////////////////////////////////////////

/**
 * wrap input [Callable] to [TtlCallable].
 *
 * @see TtlCallable.get
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <V> Callable<V>.ttlWrap(
    releaseTtlValueReferenceAfterCall: Boolean = false,
    idempotent: Boolean = false
): TtlCallable<V> = TtlCallable.get(this, releaseTtlValueReferenceAfterCall, idempotent) as TtlCallable<V>

/**
 * unwrap [TtlCallable] to the original/underneath one.
 *
 * @see TtlCallable.ttlUnwrap
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <V> Callable<V>.ttlUnwrap(): Callable<V> = TtlCallable.unwrap(this) as Callable<V>

/**
 * wrap input [Callable] collection to [TtlCallable] collection.
 *
 * @see TtlCallable.gets
 */
@JvmName("ttlWrapCallableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun <V> Collection<Callable<V>>?.ttlWrap(
    releaseTtlValueReferenceAfterCall: Boolean = false,
    idempotent: Boolean = false
): List<TtlCallable<V>> = TtlCallable.gets(this, releaseTtlValueReferenceAfterCall, idempotent)

/**
 * wrap nullable input [Callable] collection to [TtlCallable] collection.
 *
 * @see TtlCallable.gets
 */
@JvmName("ttlWrapNullableCallableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun <V> Collection<Callable<V>?>?.ttlWrap(
    releaseTtlValueReferenceAfterCall: Boolean = false,
    idempotent: Boolean = false
): List<TtlCallable<V>?> = TtlCallable.gets(this, releaseTtlValueReferenceAfterCall, idempotent)

/**
 * unwrap [TtlCallable] to the original/underneath one for collection.
 *
 * @see TtlCallable.unwraps
 */
@JvmName("ttlUnwrapCallableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun <V> Collection<Callable<V>>?.ttlUnwrap(): List<Callable<V>> =
    TtlCallable.unwraps(this)

/**
 * unwrap nullable [TtlCallable] to the original/underneath one for collection.
 *
 * @see TtlCallable.unwraps
 */
@JvmName("ttlUnwrapNullableCallableCollection")
@Suppress("NOTHING_TO_INLINE")
inline fun <V> Collection<Callable<V>?>?.ttlUnwrap(): List<Callable<V>?> =
    TtlCallable.unwraps(this)


////////////////////////////////////////
// java common functional interface
////////////////////////////////////////

/**
 * wrap [Supplier] to TTL wrapper.
 *
 * @see TtlWrappers.wrapSupplier
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T> Supplier<T>.ttlWrap(): Supplier<T> = TtlWrappers.wrapSupplier(this) as Supplier<T>

/**
 * wrap [Consumer] to TTL wrapper.
 *
 * @see TtlWrappers.wrapConsumer
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T> Consumer<T>.ttlWrap(): Consumer<T> = TtlWrappers.wrapConsumer(this) as Consumer<T>

/**
 * wrap [BiConsumer] to TTL wrapper.
 *
 * @see TtlWrappers.wrapBiConsumer
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T, U> BiConsumer<T, U>.ttlWrap(): BiConsumer<T, U> = TtlWrappers.wrapBiConsumer(this) as BiConsumer<T, U>

/**
 * wrap [Function] to TTL wrapper.
 *
 * @see TtlWrappers.wrapFunction
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T, R> Function<T, R>.ttlWrap(): Function<T, R> =
    TtlWrappers.wrapFunction(this) as Function<T, R>

/**
 * wrap [BiFunction] to TTL wrapper.
 *
 * @see TtlWrappers.wrapFunction
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T, U, R> BiFunction<T, U, R>.ttlWrap(): BiFunction<T, U, R> =
    TtlWrappers.wrapBiFunction(this) as BiFunction<T, U, R>


////////////////////////////////////////
// kotlin function types
////////////////////////////////////////

/**
 * wrap to TTL wrapper.
 */
fun <R> (() -> R).ttlWrap(): () -> R {
    if (this is TtlEnhanced) return this

    val captured = Transmitter.capture()

    return object : () -> R, TtlWrapper<() -> R> {
        override fun unwrap(): () -> R = this@ttlWrap

        override fun invoke(): R = ttlRun(captured) { this@ttlWrap.invoke() }
    }
}

/**
 * wrap to TTL wrapper.
 */
fun <P1, R> ((P1) -> R).ttlWrap(): (P1) -> R {
    if (this is TtlEnhanced) return this

    val captured = Transmitter.capture()

    return object : (P1) -> R, TtlWrapper<(P1) -> R> {
        override fun unwrap(): (P1) -> R = this@ttlWrap

        override fun invoke(arg: P1): R = ttlRun(captured) { this@ttlWrap.invoke(arg) }
    }
}

/**
 * wrap to TTL wrapper.
 */
fun <P1, P2, R> ((P1, P2) -> R).ttlWrap(): (P1, P2) -> R {
    if (this is TtlEnhanced) return this

    val captured = Transmitter.capture()

    return object : (P1, P2) -> R, TtlWrapper<(P1, P2) -> R> {
        override fun unwrap(): (P1, P2) -> R = this@ttlWrap

        override fun invoke(arg1: P1, arg2: P2): R = ttlRun(captured) { this@ttlWrap.invoke(arg1, arg2) }
    }
}

/**
 * wrap to TTL wrapper.
 */
fun <P1, P2, P3, R> ((P1, P2, P3) -> R).ttlWrap(): (P1, P2, P3) -> R {
    if (this is TtlEnhanced) return this

    val captured = Transmitter.capture()

    return object : (P1, P2, P3) -> R, TtlWrapper<(P1, P2, P3) -> R> {
        override fun unwrap(): (P1, P2, P3) -> R = this@ttlWrap

        override fun invoke(arg1: P1, arg2: P2, arg3: P3): R =
            ttlRun(captured) { this@ttlWrap.invoke(arg1, arg2, arg3) }
    }
}

/**
 * wrap to TTL wrapper.
 */
fun <P1, P2, P3, P4, R> ((P1, P2, P3, P4) -> R).ttlWrap(): (P1, P2, P3, P4) -> R {
    if (this is TtlEnhanced) return this

    val captured = Transmitter.capture()

    return object : (P1, P2, P3, P4) -> R, TtlWrapper<(P1, P2, P3, P4) -> R> {
        override fun unwrap(): (P1, P2, P3, P4) -> R = this@ttlWrap

        override fun invoke(arg1: P1, arg2: P2, arg3: P3, arg4: P4): R =
            ttlRun(captured) { this@ttlWrap.invoke(arg1, arg2, arg3, arg4) }
    }
}


////////////////////////////////////////
// Generic unwrap/check method
////////////////////////////////////////

/**
 * generic unwrap method, unwrap [TtlWrapper] to the original/underneath one.
 *
 * if input parameter is not a [TtlWrapper] just return input.
 *
 * @see TtlWrappers.unwrap
 */
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
inline fun <T> T.ttlUnwrap(): T = TtlWrappers.unwrap(this) as T

/**
 * check the input object is a `TtlWrapper` or not.
 *
 * @see TtlWrappers.isWrapper
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <T> T.isTtlWrapper(): Boolean = TtlWrappers.isWrapper(this)


////////////////////////////////////////
// Executor
////////////////////////////////////////

/**
 * wrap input [Executor] to `TtlExecutor`.
 *
 * @see TtlExecutors.getTtlExecutor
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Executor.ttlWrap(): Executor =
    TtlExecutors.getTtlExecutor(this) as Executor

/**
 * wrap input [ExecutorService] to `TtlExecutorService`.
 *
 * @see TtlExecutors.getTtlExecutorService
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ExecutorService.ttlWrap(): ExecutorService =
    TtlExecutors.getTtlExecutorService(this) as ExecutorService

/**
 * wrap input [ScheduledExecutorService] to `TtlScheduledExecutorService`.
 *
 * @see TtlExecutors.getTtlScheduledExecutorService
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ScheduledExecutorService.ttlWrap(): ScheduledExecutorService =
    TtlExecutors.getTtlScheduledExecutorService(this) as ScheduledExecutorService

/**
 * check the executor is a TTL executor wrapper or not.
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Executor?.isTtlExecutor(): Boolean = TtlExecutors.isTtlExecutor(this)

/**
 * unwrap `TtlExecutor` to the original/underneath one.
 *
 * @see TtlExecutors.unwrapTtlExecutor
 */
@Suppress("NOTHING_TO_INLINE")
inline fun <E : Executor> E.ttlUnwrap(): E = TtlExecutors.unwrapTtlExecutor(this) as E


////////////////////////////////////////
// Thread Factory
////////////////////////////////////////

/**
 * wrapper of [ThreadFactory], disable inheritable.
 *
 * @see TtlExecutors.getDisableInheritableThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ThreadFactory.ttlWrapToDisableInheritableThreadFactory(): ThreadFactory =
    TtlExecutors.getDisableInheritableThreadFactory(this) as ThreadFactory

/**
 * wrapper of [Executors.defaultThreadFactory], disable inheritable.
 *
 * @see TtlExecutors.getDefaultDisableInheritableThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun getDefaultDisableInheritableThreadFactory(): ThreadFactory =
    TtlExecutors.getDefaultDisableInheritableThreadFactory()

/**
 * check the [ThreadFactory] is `DisableInheritableThreadFactory` or not.
 *
 * @see TtlExecutors.isDisableInheritableThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ThreadFactory?.isDisableInheritableThreadFactory(): Boolean =
    TtlExecutors.isDisableInheritableThreadFactory(this)

/**
 * unwrap `DisableInheritableThreadFactory` to the original/underneath one.
 *
 * @see TtlExecutors.unwrapDisableInheritableThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ThreadFactory.ttlUnwrapDisableInheritableThreadFactory(): ThreadFactory =
    TtlExecutors.unwrapDisableInheritableThreadFactory(this) as ThreadFactory


/**
 * wrapper of [ForkJoinWorkerThreadFactory], disable inheritable.
 *
 * @see TtlExecutors.getDisableInheritableForkJoinWorkerThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ForkJoinWorkerThreadFactory.ttlWrapToDisableInheritableForkJoinWorkerThreadFactory(): ForkJoinWorkerThreadFactory =
    TtlExecutors.getDisableInheritableForkJoinWorkerThreadFactory(this) as ForkJoinWorkerThreadFactory

/**
 * wrapper of [ForkJoinPool.defaultForkJoinWorkerThreadFactory], disable inheritable.
 *
 * @see TtlExecutors.getDefaultDisableInheritableForkJoinWorkerThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun getDefaultDisableInheritableForkJoinWorkerThreadFactory(): ForkJoinWorkerThreadFactory =
    TtlExecutors.getDefaultDisableInheritableForkJoinWorkerThreadFactory()

/**
 * check the [ForkJoinWorkerThreadFactory] is `DisableInheritableForkJoinWorkerThreadFactory` or not.
 *
 * @see TtlExecutors.isDisableInheritableForkJoinWorkerThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ForkJoinWorkerThreadFactory?.isDisableInheritableForkJoinWorkerThreadFactory(): Boolean =
    TtlExecutors.isDisableInheritableForkJoinWorkerThreadFactory(this)

/**
 * unwrap `DisableInheritableForkJoinWorkerThreadFactory` to the original/underneath one.
 *
 * @see TtlExecutors.unwrapDisableInheritableForkJoinWorkerThreadFactory
 */
@Suppress("NOTHING_TO_INLINE")
inline fun ForkJoinWorkerThreadFactory.ttlUnwrapDisableInheritableForkJoinWorkerThreadFactory(): ForkJoinWorkerThreadFactory =
    TtlExecutors.unwrapDisableInheritableForkJoinWorkerThreadFactory(this) as ForkJoinWorkerThreadFactory


////////////////////////////////////////
// Comparator
////////////////////////////////////////

/**
 * wrapper of `Comparator<Runnable>` which unwrap [TtlRunnable] before compare,
 * aka `TtlRunnableUnwrapComparator`.
 *
 * @see TtlExecutors.getTtlRunnableUnwrapComparator
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Comparator<Runnable>.ttlWrapToTtlRunnableUnwrapComparator() =
    TtlExecutors.getTtlRunnableUnwrapComparator(this) as Comparator<Runnable>

/**
 * `TtlRunnableUnwrapComparator` that compares {@link Comparable Comparable} objects.
 *
 * @see TtlExecutors.getTtlRunnableUnwrapComparatorForComparableRunnable
 */
@Suppress("NOTHING_TO_INLINE")
inline fun getTtlRunnableUnwrapComparatorForComparableRunnable(): Comparator<Runnable> =
    TtlExecutors.getTtlRunnableUnwrapComparatorForComparableRunnable()

/**
 * check the `Comparator<Runnable>` is a wrapper `TtlRunnableUnwrapComparator` or not.
 *
 * @see TtlExecutors.isTtlRunnableUnwrapComparator
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Comparator<Runnable>?.isTtlRunnableUnwrapComparator(): Boolean =
    TtlExecutors.isTtlRunnableUnwrapComparator(this)

/**
 * unwrap `TtlRunnableUnwrapComparator` to the original/underneath `Comparator<Runnable>`.
 *
 * @see TtlExecutors.unwrapTtlRunnableUnwrapComparator
 */
@Suppress("NOTHING_TO_INLINE")
inline fun Comparator<Runnable>.ttlUnwrapTtlRunnableUnwrapComparator(): Comparator<Runnable> =
    TtlExecutors.unwrapTtlRunnableUnwrapComparator(this) as Comparator<Runnable>