-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2. ttl Delegate 3. ttl callable extensions
- Loading branch information
1 parent
19dbff2
commit 6fdc467
Showing
5 changed files
with
180 additions
and
1 deletion.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
src/main/java/com/alibaba/ttl/TransmittableThreadLocalExt.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.alibaba.ttl | ||
|
||
import kotlin.reflect.KProperty | ||
|
||
fun <T> ttl() = TransmittableThreadLocal<T?>() | ||
|
||
class TtlDelegate<T> { | ||
private var _value = ttl<T>() | ||
|
||
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? = _value.get() | ||
|
||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { | ||
_value.set(value) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.alibaba.ttl | ||
|
||
import java.util.concurrent.Callable | ||
|
||
@Throws(Exception::class) | ||
operator fun <V> TtlCallable<V>.invoke(): V = call() | ||
|
||
/** | ||
* Extension function wrap {@link Callable} into {@link TtlCallable}. | ||
* <p> | ||
* | ||
* @param releaseTtlValueReferenceAfterCall release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. | ||
* @param idempotent is idempotent or not. {@code true} will cover up bugs! <b>DO NOT</b> set, only when you know why. | ||
* @return Wrapped {@link Callable} | ||
* | ||
* * @since TODO | ||
*/ | ||
fun <V> Callable<V>.wrap( | ||
releaseTtlValueReferenceAfterCall: Boolean = false, | ||
idempotent: Boolean = false | ||
): TtlCallable<V> = TtlCallable.get(this, releaseTtlValueReferenceAfterCall, idempotent)!! | ||
|
||
/** | ||
* Extension function wrap input {@link Callable} Collection to {@link TtlCallable} Collection. | ||
* | ||
* @param releaseTtlValueReferenceAfterCall release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred. | ||
* @param idempotent is idempotent or not. {@code true} will cover up bugs! <b>DO NOT</b> set, only when you know why. | ||
* @return Wrapped list of {@link Callable} | ||
* | ||
* @see #Callable::wrap | ||
* @since TODO | ||
*/ | ||
fun <V> List<Callable<V>>.wrap( | ||
releaseTtlValueReferenceAfterCall: Boolean = false, | ||
idempotent: Boolean = false | ||
): List<TtlCallable<V>> = map { it.wrap(releaseTtlValueReferenceAfterCall, idempotent) } | ||
|
||
/** | ||
* Extension function to unwrap {@link TtlCallable} to the original/underneath one. | ||
* <p> | ||
* if input {@code Callable} parameter is not a {@link TtlCallable} just return input {@code Callable}. | ||
* <p> | ||
* so {@code callable.wrap().unwrap()} will always return the same input {@code callable} object. | ||
* | ||
* @since TODO | ||
*/ | ||
fun <V> Callable<V>.unwrap(): Callable<V> = when(this) { | ||
is TtlCallable<V> -> getCallable() | ||
else -> this | ||
} | ||
|
||
/** | ||
* Extension function to unwrap {@link TtlCallable} to the original/underneath one. | ||
* <p> | ||
* Invoke {@link #unwrap(Callable)} for each element in collection. | ||
* <p> | ||
* | ||
* @see #Callable::unwrap | ||
* @since TODO | ||
*/ | ||
fun <V> List<Callable<V>>.unwrap() : List<Callable<V>> = map { it.unwrap() } |
30 changes: 30 additions & 0 deletions
30
src/test/java/com/alibaba/ttl/TransmittableThreadLocalExtKtTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.alibaba.ttl | ||
|
||
import junit.framework.TestCase.assertEquals | ||
import junit.framework.TestCase.assertNotNull | ||
import org.junit.Test | ||
import kotlin.concurrent.thread | ||
|
||
class TransmittableThreadLocalExtKtTest { | ||
|
||
@Test | ||
fun `ttl delegate`() { | ||
var parent by TtlDelegate<String>() | ||
parent = "value-set-in-parent" | ||
thread { | ||
val valueFromParent = parent | ||
assertEquals("value-set-in-parent", valueFromParent) | ||
}.join() | ||
|
||
} | ||
|
||
@Test | ||
fun `ttl nullable delegate`() { | ||
val parent by TtlDelegate<Int>() | ||
|
||
thread { | ||
assertNotNull("value-set-in-parent", parent) | ||
}.join() | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.alibaba.ttl | ||
|
||
import com.alibaba.assertChildTtlValues | ||
import com.alibaba.assertParentTtlValues | ||
import com.alibaba.copyTtlValues | ||
import com.alibaba.createParentTtlInstances | ||
import com.alibaba.createParentTtlInstancesAfterCreateChild | ||
import com.alibaba.ttl.testmodel.Call | ||
import org.hamcrest.CoreMatchers | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Assert.assertSame | ||
import org.junit.Assert.assertThat | ||
import org.junit.Assert.fail | ||
import org.junit.Test | ||
|
||
class TtlCallableExtKtTest { | ||
|
||
@Test | ||
fun `callable wrap extension function `() { | ||
val call = Call("1") | ||
val ttlCallable = call.wrap() | ||
assertSame(call, ttlCallable.callable) | ||
} | ||
|
||
@Test | ||
fun `callable wrap extension function multiple times`() { | ||
val call = Call("1").wrap() | ||
try { | ||
call.wrap() | ||
fail() | ||
} catch (e: IllegalStateException) { | ||
assertThat<String>(e.message, CoreMatchers.containsString("Already TtlCallable")) | ||
} | ||
|
||
} | ||
|
||
@Test | ||
fun `list of callable wrap extension function`() { | ||
val callList = listOf(Call("1"), Call("2"), Call("3")).wrap() | ||
|
||
assertEquals(3, callList.size) | ||
callList.forEach { | ||
assertThat(it, CoreMatchers.instanceOf(TtlCallable::class.java)) | ||
} | ||
} | ||
|
||
@Test | ||
fun `TtlCallable invoke operator`() { | ||
val ttlInstances = createParentTtlInstances() | ||
|
||
val call = Call("1", ttlInstances) | ||
|
||
|
||
val ttlCallable = call.wrap() | ||
|
||
// create after new Task, won't see parent value in in task! | ||
createParentTtlInstancesAfterCreateChild(ttlInstances) | ||
|
||
// run in the *current* thread | ||
assertEquals("ok", ttlCallable()) | ||
|
||
|
||
// child Inheritable | ||
assertChildTtlValues("1", call.copied) | ||
|
||
// child do not effect parent | ||
assertParentTtlValues(copyTtlValues(ttlInstances)) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters