Skip to content

Commit

Permalink
Extension function to convert a ListenableFuture to a CompletableFutu…
Browse files Browse the repository at this point in the history
…re (#8)

* Added an extension function to convert a ListenableFuture to a CompletableFuture

* Using a bigger delay.
  • Loading branch information
vjames19 authored Aug 6, 2018
1 parent 52b52aa commit 3629778
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 25 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,6 @@ subprojects {
}

task wrapper(type: Wrapper) {
gradleVersion = "4.8.1"
gradleVersion = "3.5"
distributionType = org.gradle.api.tasks.wrapper.Wrapper.DistributionType.ALL
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
3 changes: 1 addition & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Sun Aug 05 14:30:33 CDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip
6 changes: 3 additions & 3 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
warn () {
echo "$*"
}

die ( ) {
die () {
echo
echo "$*"
echo
Expand Down Expand Up @@ -155,7 +155,7 @@ if $cygwin ; then
fi

# Escape application args
save ( ) {
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
Expand Down
3 changes: 3 additions & 0 deletions kotlin-futures-guava-to-jdk8/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
compile project(":kotlin-futures-guava")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.github.vjames19.futures.guava

import com.google.common.util.concurrent.ListenableFuture
import io.github.vjames19.futures.jdk8.DirectExecutor
import io.github.vjames19.futures.jdk8.onComplete
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor

fun <T> ListenableFuture<T>.toCompletableFuture(executor: Executor = DirectExecutor): CompletableFuture<T> {
val future = CompletableFuture<T>()

onComplete(
executor = executor,
onFailure = { future.completeExceptionally(it) },
onSuccess = { future.complete(it)}
)

return future
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.github.vjames19.futures.guava

import io.github.vjames19.futures.jdk8.ImmediateFuture
import io.github.vjames19.futures.jdk8.toListenableFuture
import org.amshove.kluent.shouldEqualTo
import org.amshove.kluent.shouldThrowTheException
import org.amshove.kluent.withCause
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe
import org.jetbrains.spek.api.dsl.given
import org.jetbrains.spek.api.dsl.it
import java.util.concurrent.ExecutionException


object ListenableFutureToCompletableFutureSpec : Spek({

describe("toCompletableFuture") {
given("a successful future") {
it("it should be able to return a successful CompletableFuture") {
val listenableFuture = ImmediateFuture { 10 }
val future = listenableFuture.toCompletableFuture()

future.isDone shouldEqualTo true
future.isCompletedExceptionally shouldEqualTo false

future.get() shouldEqualTo 10
}
}

given("a failed future") {
it("should return the exception returned by the ListenableFuture") {
val listenableFuture = IllegalArgumentException().toListenableFuture<String>()
val future = listenableFuture.toCompletableFuture()

({ future.get() }) shouldThrowTheException ExecutionException::class withCause IllegalArgumentException::class
}
}
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package io.github.vjames19.futures.jdk8

import com.google.common.util.concurrent.*
import java.util.*
import java.util.concurrent.*
import java.util.function.BiConsumer
import java.util.function.BiFunction
import java.util.function.Function
import java.util.function.Supplier
import java.util.concurrent.Callable
import java.util.concurrent.Executor
import java.util.concurrent.ExecutorService
import java.util.concurrent.ForkJoinPool

// Creation
inline fun <A> Future(executor: ExecutorService = ForkJoinExecutor, crossinline block: () -> A): ListenableFuture<A> {
Expand Down Expand Up @@ -45,15 +44,21 @@ inline fun <A> ListenableFuture<A>.recover(crossinline f: (Throwable) -> A): Lis
Futures.catching(this, Throwable::class.java) { f(it!!.cause ?: it) }

inline fun <A> ListenableFuture<A>.recoverWith(executor: Executor = ForkJoinExecutor, crossinline f: (Throwable) -> ListenableFuture<A>): ListenableFuture<A> {
return Futures.catchingAsync(this, Throwable::class.java) { f(it!!.cause ?: it)}
return Futures.catchingAsync(
this,
Throwable::class.java,
AsyncFunction<Throwable, A> { throwable -> f(throwable!!.cause ?: throwable) },
executor
)
}


inline fun <A, reified E : Throwable> ListenableFuture<A>.mapError(crossinline f: (E) -> Throwable): ListenableFuture<A> {
return Futures.catching(this, E::class.java) { throw f(it!!) }
}

inline fun <A> ListenableFuture<A>.fallbackTo(executor: Executor = ForkJoinExecutor, crossinline f: () -> ListenableFuture<A>): ListenableFuture<A> =
recoverWith(executor, { f() })
recoverWith(executor) { f() }


// Callbacks
Expand Down Expand Up @@ -82,6 +87,7 @@ inline fun <A> ListenableFuture<A>.onSuccess(executor: Executor = ForkJoinExecut
}

inline fun <A> ListenableFuture<A>.onComplete(executor: Executor = ForkJoinExecutor, crossinline onFailure: (Throwable) -> Unit, crossinline onSuccess: (A) -> Unit): ListenableFuture<A> {

Futures.addCallback(this, object : FutureCallback<A> {
override fun onSuccess(result: A?) {
onSuccess(result!!)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.github.vjames19.futures.jdk8
package io.github.vjames19.futures.guava

import com.google.common.util.concurrent.ListenableFuture
import io.github.vjames19.futures.jdk8.*
import org.amshove.kluent.*
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe
import org.jetbrains.spek.api.dsl.given
import org.jetbrains.spek.api.dsl.it
import org.jetbrains.spek.api.dsl.on
import java.util.concurrent.CompletableFuture

/**
* Created by victor.reventos on 7/1/17.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ object FutureSpec : Spek({

given("a successful future") {
it("should return the first completed") {
val f3 = Future { Thread.sleep(3000); 3 }
val f2 = Future { Thread.sleep(2000); 2 }
val f1 = Future { Thread.sleep(1); 1 }
val f3 = Future { Thread.sleep(30000); 3 }
val f2 = Future { Thread.sleep(20000); 2 }
val f1 = ImmediateFuture { 1 }


withFutures(listOf(f3, f2, f1)) {
Expand All @@ -229,9 +229,9 @@ object FutureSpec : Spek({
given("that its the first to complete") {
it("should return it") {

val f3 = Future { Thread.sleep(3000); 3 }
val f2 = Future { Thread.sleep(2000); 2 }
val f1 = Future<Int> { Thread.sleep(1); throw IllegalArgumentException() }
val f3 = Future { Thread.sleep(30000); 3 }
val f2 = Future { Thread.sleep(20000); 2 }
val f1 = ImmediateFuture<Int> { throw IllegalArgumentException() }
withFutures(listOf(f3, f2, f1)) {
({ Future.firstCompletedOf(it).get() }) shouldThrow AnyException
}
Expand All @@ -240,9 +240,9 @@ object FutureSpec : Spek({

given("that its not the first one to complete") {
it("should return the first one") {
val f3 = Future { Thread.sleep(3000); 3 }
val f2 = Future<Int> { Thread.sleep(2000); throw IllegalArgumentException() }
val f1 = Future { Thread.sleep(1); 1 }
val f3 = Future { Thread.sleep(30000); 3 }
val f2 = Future<Int> { Thread.sleep(20000); throw IllegalArgumentException() }
val f1 = ImmediateFuture { 1 }

withFutures(listOf(f3, f2, f1)) {
Future.firstCompletedOf(listOf(f3, f2, f1)).get() shouldEqual 1
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ include 'services:webservice'
rootProject.name = 'kotlin-futures'

include 'kotlin-futures-jdk8'
include 'kotlin-futures-guava'
include 'kotlin-futures-guava'
include 'kotlin-futures-guava-to-jdk8'

0 comments on commit 3629778

Please sign in to comment.