Skip to content

Commit

Permalink
Merge branch 'release/v3.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
mplatvoet committed Feb 28, 2016
2 parents c2004af + bbc365a commit acde483
Show file tree
Hide file tree
Showing 21 changed files with 1,047 additions and 65 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ master: [![Master dependency status](https://www.versioneye.com/user/projects/55
#Kovenant
[Promises](http://en.wikipedia.org/wiki/Futures_and_promises) for [Kotlin](http://kotlinlang.org).

The easy asynchronous library for Kotlin. With extensions for Android, LMAX Disruptor, JavaFX and much more.
The easy asynchronous library for Kotlin. With extensions for Android, RxJava, JavaFX and much more.

```kt
task { "world" } and task { "Hello" } success {
Expand All @@ -23,7 +23,7 @@ Source and target compatibility is `1.6`
###Gradle
```groovy
dependencies {
compile 'nl.komponents.kovenant:kovenant:3.0.0'
compile 'nl.komponents.kovenant:kovenant:3.1.0'
}
```

Expand All @@ -32,7 +32,7 @@ dependencies {
<dependency>
<groupId>nl.komponents.kovenant</groupId>
<artifactId>kovenant</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
</dependency>
```

Expand All @@ -49,6 +49,7 @@ Kovenant has been structured in sub projects so you can cherry pick what you nee
|kovenant-combine |Adds combine functionality that keep everything strongly typed |
|kovenant-jvm |Support for converting between Executors and Dispatchers |
|kovenant-ui |Support for UI frameworks that need UI work to operate on a specific process |
|kovenant-rx |Add promise support to Rx |
|kovenant-android |Extensions for Android specific needs |
|kovenant-jfx |Extensions for JavaFX specific needs |
|kovenant-disruptor |LMAX Disruptor work queues |
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ buildscript {

allprojects {
ext {
appVersion = '3.0.0'
appVersion = '3.1.0'
appGroup = 'nl.komponents.kovenant'


Expand Down
92 changes: 92 additions & 0 deletions docs/docs/addons/rx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#Rx features
part of [`kovenant-rx`](../index.md#artifacts)

---
Addon project for converting back and forth between `Kovenant` `Promise`s and rx `Observable`s.


##ToPromise
Any `Observable` can be turned into a `Promise` but understand that there is a fundamental difference between the two.
A `Promise` represents a single value that either is successful or failed. An `Observable` on the other hand represents
a stream of values which results in the following possible states:

* emit nothing.
* emit an error.
* emit completed without data
* emit completed after single value
* emit completed after multiple values
* emit multiple values but never completed

To convert from an `Observable` to a `Promise` you simply do:

```kt
val values = arrayOf(1, 2, 3, 4, 5)
val observable = Observable.from(values)
val promise = observable.toPromise()
```

By default `toPromise()` will create a promise that will resolve successful with the first emitted value. It will
resolve as failed if there are no values emitted but the `Observable` emits completed. This will thus lead to:

* emit nothing - _promise doesn't complete_
* emit an error - _promise resolves as failed, if no other value was emitted_
* emit completed without data - _promise resolves as failed_
* emit completed after single value - _promise resolves successful with value_
* emit completed after multiple values - _promise resolves successful with first value_
* emit multiple values but never completed - _promise resolves successful with first value_

###EmitStrategy
By default `toPromise()` resolves successful with the first emitted value. If you'd rather resolve by the last emitted
value you can change the behaviour by calling:

```kt
val promise = observable.toPromise(strategy = EmitStrategy.LAST)
```

###EmptyPolicy
By default `toPromise()` resolves as failed if the `Observable` is completed but hasn't emitted a value. To control
the behaviour of the promise when the `Observable` is empty you can create one of the following EmptyPolicies:

```kt
//resolve with value
EmptyPolicy.resolve (42)

//resolve with factory value
EmptyPolicy.resolve { 42 }

//reject with eception
EmptyPolicy.reject(Exception())

//reject with exception factory
EmptyPolicy.reject { Exception() }

```

And you can use them like this:

```kt
val promise = observable.toPromise(emptyPolicy = EmptyPolicy.resolve (42))
```

There is also a shorthand for this common case, so you can always resolve successful with a default value:

```kt
val promise = observable.toPromise(42)
//or with a factory
val promise = observable.toPromise() { 42 }
```

##ToListPromise
Instead of converting an `Observable` to a single value we can also simply put al te results in a `List`. This is as
simple as:

```kt
val promise = observable.toListPromise()
```
The only requirement for this to work is that the `Observable` actually emits completed at some point in the
future.

##ToObservable

To turn a `Promise` into an `Observable` you can simply call `toObservable()`. Note that by default the
`Observable` is observed on the callback `Dispatcher` of the `Promise` in question.
11 changes: 11 additions & 0 deletions docs/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ Please refer to [roadmap](roadmap.md) for upcoming releases.

##v3.0.0

**rx**

* [KOV-68](http://issues.komponents.nl/youtrack/issue/KOV-68) Add conversion from rx::Observable to kovenant::Promise
* [KOV-69](http://issues.komponents.nl/youtrack/issue/KOV-69) Add conversion from kovenant::Promise to rx::Observable

**core**

* [KOV-70](http://issues.komponents.nl/youtrack/issue/KOV-70) Leverage sun.misc.Unsafe, fallback to AtomicFieldUpdaters

##v3.0.0

**general**

* Kotlin 1.0
Expand Down
9 changes: 5 additions & 4 deletions docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#Kovenant
[Promises](http://en.wikipedia.org/wiki/Futures_and_promises) for [Kotlin](http://kotlinlang.org)

The easy asynchronous library for Kotlin. With extensions for Android, LMAX Disruptor, JavaFX and much more.
The easy asynchronous library for Kotlin. With extensions for Android, RxJava, JavaFX and much more.

```kt
task {
Expand Down Expand Up @@ -31,7 +31,7 @@ Source and target compatibility is `1.6`
###Gradle
```groovy
dependencies {
compile 'nl.komponents.kovenant:kovenant:3.0.0'
compile 'nl.komponents.kovenant:kovenant:3.1.0'
}
```

Expand All @@ -40,7 +40,7 @@ dependencies {
<dependency>
<groupId>nl.komponents.kovenant</groupId>
<artifactId>kovenant</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
</dependency>
```

Expand All @@ -57,7 +57,8 @@ Kovenant has been structured in sub projects so you can cherry pick what you nee
|kovenant-combine |Adds combine functionality that keep everything strongly typed |
|kovenant-jvm |Support for converting between Executors and Dispatchers |
|kovenant-ui |Support for UI frameworks that need UI work to operate on a specific process |
|kovenant-android |Extensions for Android specific needs |
|kovenant-rx |Add promise support to Rx |
|kovenant-android |Extensions for Android specific needs |
|kovenant-jfx |Extensions for JavaFX specific needs |
|kovenant-disruptor |LMAX Disruptor work queues |
|kovenant-progress |Progress configuration helper |
Expand Down
10 changes: 2 additions & 8 deletions docs/docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ Input is always welcome.

---

##v3.0.0

Version 3 will be the first version build against Kotlin version 1.0 (when it arrives of course)

---

##v3.1.0
##v3.2.0

**expected**

* Java interoperability. Focus on naming and calling Kovenant from the JVM
* UI Click handler
* Groundwork for JavaScript, core only.

**certain**
Expand Down
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pages:
- 'UI': 'addons/ui.md'
- 'Disruptor': 'addons/disruptor.md'
- 'Progress': 'addons/progress.md'
- 'Rx': 'addons/rx.md'
- Misc:
- 'Goals': 'misc/goals.md'
- 'Performance': 'misc/performance.md'
Expand Down
51 changes: 51 additions & 0 deletions projects/core/src/main/kotlin/cas-jvm.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package nl.komponents.kovenant.unsafe

import sun.misc.Unsafe
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
import kotlin.reflect.KClass

class UnsafeAtomicReferenceFieldUpdater<C : Any, V : Any>(targetClass: KClass<C>,
fieldName: String) : AtomicReferenceFieldUpdater<C, V>() {
companion object {
private val unsafe = getUnsafe()
}

private val offset: Long

init {
val field = targetClass.java.getDeclaredField(fieldName)
offset = unsafe.objectFieldOffset(field)
}

override fun lazySet(target: C, newValue: V?) = unsafe.putOrderedObject(target, offset, newValue)
override fun compareAndSet(target: C, expected: V?, update: V?): Boolean = unsafe.compareAndSwapObject(target, offset, expected, update)

override fun set(target: C, newValue: V?) = unsafe.putObjectVolatile(target, offset, newValue);

@Suppress("UNCHECKED_CAST")
override fun get(target: C): V? = unsafe.getObjectVolatile(target, offset) as V

//Equals AtomicReferenceFieldUpdater implementation on Java 8
override fun weakCompareAndSet(target: C, expected: V?, update: V?): Boolean = compareAndSet(target, expected, update)
}


fun hasUnsafe(): Boolean {
try {
Class.forName("sun.misc.Unsafe")
return true
} catch(e: ClassNotFoundException) {
return false
}
}

private fun getUnsafe(): Unsafe {
try {
val field = Unsafe::class.java.getDeclaredField("theUnsafe");
field.isAccessible = true;
return field.get(null) as Unsafe;

} catch (e: Exception) {
throw RuntimeException("unsafe doesn't exist or is not accessible")
}
}
4 changes: 3 additions & 1 deletion projects/core/src/main/kotlin/exceptions-api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ open class ConfigurationException(message: String) : KovenantException(message)

open class FailedException(val error: Any?) : KovenantException(error.toString())

open class UnsupportedException(message: String? = null, cause: Exception? = null) : KovenantException(message, cause)
open class UnsupportedException(message: String? = null, cause: Exception? = null) : KovenantException(message, cause)

open class EmptyException(message: String? = null, cause: Exception? = null) : KovenantException(message, cause)
Loading

0 comments on commit acde483

Please sign in to comment.