Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semaphore #1151

Merged
merged 26 commits into from
Nov 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a7349b4
Add Promise
nomisRev Nov 16, 2018
fcbe27a
Promise based on Async
nomisRev Nov 16, 2018
972787b
Merge branch 'master' into simon-promise
nomisRev Nov 16, 2018
55f0a49
Promise tests
nomisRev Nov 16, 2018
66d0b3b
Merge branch 'simon-promise' of github.com:arrow-kt/arrow into simon-…
nomisRev Nov 16, 2018
f3bd536
Merge branch 'master' into simon-promise
nomisRev Nov 17, 2018
2b07706
Update API
nomisRev Nov 18, 2018
8c94327
Add docs
nomisRev Nov 19, 2018
2c466bd
Merge branch 'master' into simon-promise
nomisRev Nov 19, 2018
23e6835
Missing imports docs
nomisRev Nov 19, 2018
9b6ae0e
Merge branch 'simon-promise' of github.com:arrow-kt/arrow into simon-…
nomisRev Nov 19, 2018
ca29740
Add Semaphore
nomisRev Nov 19, 2018
f652b4d
Add Semaphore
nomisRev Nov 19, 2018
c877c6d
Add docs
nomisRev Nov 19, 2018
9dfe5ce
Semaphore Kdoc
nomisRev Nov 21, 2018
758e3e9
Merge branch 'master' into simon-semaphore
nomisRev Nov 21, 2018
29a4ac6
Fix docs
nomisRev Nov 21, 2018
08b7f32
Merge branch 'simon-semaphore' of github.com:arrow-kt/arrow into simo…
nomisRev Nov 21, 2018
cbd463c
Detekt fix
nomisRev Nov 21, 2018
5ba43e2
Merge branch 'master' into simon-semaphore
raulraja Nov 21, 2018
1707142
Fix semaphore docs
nomisRev Nov 22, 2018
9b08e46
Fix Promise docs
nomisRev Nov 22, 2018
c5237d2
Fix typo in docs
nomisRev Nov 22, 2018
94e6d35
Merge branch 'master' into simon-semaphore
nomisRev Nov 22, 2018
bc002e9
remove unused imports
nomisRev Nov 22, 2018
e50589f
Merge branch 'master' into simon-semaphore
nomisRev Nov 22, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions modules/docs/arrow-docs/docs/docs/effects/promise/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ A `Promise` guarantees (promises) `A` at some point in the future within the con

## Constructing a Promise

A promise can easily be made by calling `cancellable`.
A promise can easily be made by calling `uncancelable`.
Since the allocation of mutable state is not referentially transparent this side-effect is contained within `F`.

{: data-executable='true'}
Expand All @@ -31,7 +31,7 @@ println(promise)
}
```

In case you want the side-effect to execute immediately and return the `Ref` instance you can use the `unsafe` function.
In case you want the side-effect to execute immediately and return the `Promise` instance you can use the `unsafeUncancelable` function.

{: data-executable='true'}
```kotlin:ank
Expand All @@ -40,7 +40,7 @@ import arrow.effects.instances.io.async.async

fun main(args: Array<String>) {
//sampleStart
val unsafePromise: Promise<ForIO, Int> = Promise.unsafeCancellable(IO.async())
val unsafePromise: Promise<ForIO, Int> = Promise.unsafeUncancelable(IO.async())
//sampleEnd
println(unsafePromise)
}
Expand Down
8 changes: 5 additions & 3 deletions modules/docs/arrow-docs/docs/docs/effects/ref/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Most operators found on `AtomicReference` can also be found on `Ref` within the

```kotlin:ank
ioRef.flatMap { ref ->
ref.get()
ref.get
}.unsafeRunSync()
```
```kotlin:ank
Expand All @@ -58,10 +58,12 @@ ioRef.flatMap { ref ->
```
```kotlin:ank
import arrow.core.toT
import arrow.effects.instances.io.monad.flatMap
import arrow.effects.instances.io.monad.map

ioRef.flatMap { ref ->
ref.getAndSet(5).fix().flatMap { old ->
ref.get().fix().map { new -> old toT new }
ref.getAndSet(5).flatMap { old ->
ref.get.map { new -> old toT new }
}
}.unsafeRunSync()
```
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class RefTest : UnitSpec() {
forAll(Gen.int(), Gen.int()) { a, b ->
Ref.of(a, IO.monadDefer()).flatMap { ref ->
ref.set(b).flatMap { _ ->
ref.get().map { get ->
ref.get.map { get ->
get == b
}
}
Expand All @@ -29,7 +29,7 @@ class RefTest : UnitSpec() {
forAll(Gen.int(), Gen.int()) { a, b ->
Ref.of(a, this).flatMap { ref ->
ref.getAndSet(b).flatMap { old ->
ref.get().map { new ->
ref.get.map { new ->
old == a && new == b
}
}
Expand All @@ -39,8 +39,8 @@ class RefTest : UnitSpec() {

"consistent set update" {
forAll(Gen.int(), Gen.int()) { a, b ->
val set = Ref.of(a, this).flatMap { ref -> ref.set(b).flatMap { _ -> ref.get() } }
val update = Ref.of(a, this).flatMap { ref -> ref.update { _ -> b }.flatMap { _ -> ref.get() } }
val set = Ref.of(a, this).flatMap { ref -> ref.set(b).flatMap { _ -> ref.get } }
val update = Ref.of(a, this).flatMap { ref -> ref.update { _ -> b }.flatMap { _ -> ref.get } }

set.flatMap { setA ->
update.map { updateA ->
Expand All @@ -54,7 +54,7 @@ class RefTest : UnitSpec() {
forAll(Gen.int()) { a ->
Ref.of(a, this).flatMap { ref ->
ref.access().map { (a, _) -> a }.flatMap { _ ->
ref.get().map { get ->
ref.get.map { get ->
get == a
}
}
Expand All @@ -77,7 +77,7 @@ class RefTest : UnitSpec() {
val ref = Ref.of(a, this@with).bind()
val (_, setter) = ref.access().bind()
val success = setter(b).bind()
val result = ref.get().bind()
val result = ref.get.bind()
success && result == b
}.fix().unsafeRunSync()
}
Expand All @@ -90,7 +90,7 @@ class RefTest : UnitSpec() {
val (_, setter) = ref.access().bind()
ref.set(b).bind()
val success = setter(c).bind()
val result = ref.get().bind()
val result = ref.get.bind()
!success && result == b
}.fix().unsafeRunSync()
}
Expand All @@ -104,7 +104,7 @@ class RefTest : UnitSpec() {
val cond1 = setter(b).bind()
ref.set(c).bind()
val cond2 = setter(d).bind()
val result = ref.get().bind()
val result = ref.get.bind()
cond1 && !cond2 && result == c
}.fix().unsafeRunSync()
}
Expand All @@ -114,7 +114,7 @@ class RefTest : UnitSpec() {
forAll(Gen.int(), genFunctionAToB<Int, Int>(Gen.int())) { a, f ->
Ref.of(a, this).flatMap { ref ->
ref.tryUpdate(f).flatMap {
ref.get().map { newA ->
ref.get.map { newA ->
newA == f(a)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ interface Promise<F, A> {
*
* promise.flatMap { p ->
* p.get
* }.unsafeRunTimed(3.seconds) == IO.never.unsafeRunTimed(3.seconds)
* } //Never ends since is uncancelable
*
* promise.flatMap { p ->
* p.complete(1).flatMap {
Expand Down Expand Up @@ -132,7 +132,7 @@ interface Promise<F, A> {
* }
* ```
*/
fun <F, A> uncancelable(AS: Async<F>): Kind<F, Promise<F, A>> = AS { unsafeCancellable<F, A>(AS) }
fun <F, A> uncancelable(AS: Async<F>): Kind<F, Promise<F, A>> = AS { unsafeUncancelable<F, A>(AS) }

/**
* Creates an empty `Promise` from on [Async] instance for [F].
Expand All @@ -147,21 +147,21 @@ interface Promise<F, A> {
*
* fun main(args: Array<String>) {
* //sampleStart
* val unsafePromise: Promise<ForIO, Int> = Promise.unsafeCancellable(IO.async())
* val unsafePromise: Promise<ForIO, Int> = Promise.unsafeUncancelable(IO.async())
* //sampleEnd
* }
* ```
*/
fun <F, A> unsafeCancellable(AS: Async<F>): Promise<F, A> = CancellablePromise(AS, AtomicReference(CancellablePromise.State.Pending(emptyList())))
fun <F, A> unsafeUncancelable(AS: Async<F>): Promise<F, A> = UncancelablePromise(AS, AtomicReference(UncancelablePromise.State.Pending(emptyList())))

}

object AlreadyFulfilled: Throwable(message = "Promise was already fulfilled")

}

internal class CancellablePromise<F, A> constructor(private val AS: Async<F>,
private val state: AtomicReference<State<A>>) : Promise<F, A> {
internal class UncancelablePromise<F, A> constructor(private val AS: Async<F>,
private val state: AtomicReference<State<A>>) : Promise<F, A> {

override val get: Kind<F, A> = AS.async { k: (Either<Throwable, A>) -> Unit ->
tailrec fun loop(): Unit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface Ref<F, A> {
* Obtains the current value.
* Since [Ref] is always guaranteed to have a value, the returned action completes immediately after being bound.
*/
fun get(): Kind<F, A>
val get: Kind<F, A>

/**
* Sets the current value to [a].
Expand Down Expand Up @@ -120,9 +120,10 @@ interface Ref<F, A> {
*/
private class MonadDeferRef<F, A>(private val ar: AtomicReference<A>, private val MD: MonadDefer<F>) : Ref<F, A> {

override fun get(): Kind<F, A> = MD.delay {
ar.get()
}
override val get: Kind<F, A>
get() = MD.delay {
ar.get()
}

override fun set(a: A): Kind<F, Unit> = MD.delay {
ar.set(a)
Expand All @@ -133,7 +134,7 @@ interface Ref<F, A> {
}

override fun setAndGet(a: A): Kind<F, A> = MD.run {
set(a).flatMap { get() }
set(a).flatMap { get }
}

override fun getAndUpdate(f: (A) -> A): Kind<F, A> = MD.delay {
Expand Down
Loading