Skip to content

Commit

Permalink
Added a first implementation of 'race' that makes tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
rcardin committed Jun 10, 2024
1 parent 389ab98 commit f3d8c6d
Showing 1 changed file with 43 additions and 32 deletions.
75 changes: 43 additions & 32 deletions core/src/main/scala/in/rcard/sus4s/sus4s.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package in.rcard.sus4s

import java.util.concurrent.StructuredTaskScope.ShutdownOnFailure
import java.util.concurrent.StructuredTaskScope.{ShutdownOnFailure, ShutdownOnSuccess}
import java.util.concurrent.{CompletableFuture, StructuredTaskScope}
import scala.concurrent.ExecutionException
import scala.concurrent.duration.Duration
Expand Down Expand Up @@ -58,34 +58,34 @@ object sus4s {

/** Cancels the job and all its children jobs. Getting the value of a cancelled job throws an
* [[InterruptedException]]. Cancellation is an idempotent operation.
*
* <h2>Example</h2>
* {{{
* val expectedQueue = structured {
* val queue = new ConcurrentLinkedQueue[String]()
* val job1 = fork {
* val innerJob = fork {
* fork {
* Thread.sleep(3000)
* println("inner-inner-Job")
* queue.add("inner-inner-Job")
* }
* Thread.sleep(2000)
* println("innerJob")
* queue.add("innerJob")
* }
* Thread.sleep(1000)
* queue.add("job1")
* }
* val job = fork {
* Thread.sleep(500)
* job1.cancel()
* queue.add("job2")
* }
* queue
* }
* expectedQueue.toArray should contain theSameElementsInOrderAs List("job2")
* }}}
*
* <h2>Example</h2>
* {{{
* val expectedQueue = structured {
* val queue = new ConcurrentLinkedQueue[String]()
* val job1 = fork {
* val innerJob = fork {
* fork {
* Thread.sleep(3000)
* println("inner-inner-Job")
* queue.add("inner-inner-Job")
* }
* Thread.sleep(2000)
* println("innerJob")
* queue.add("innerJob")
* }
* Thread.sleep(1000)
* queue.add("job1")
* }
* val job = fork {
* Thread.sleep(500)
* job1.cancel()
* queue.add("job2")
* }
* queue
* }
* expectedQueue.toArray should contain theSameElementsInOrderAs List("job2")
* }}}
*/
def cancel(): Suspend ?=> Unit = {
// FIXME Refactor this code
Expand Down Expand Up @@ -209,7 +209,7 @@ object sus4s {
})
Job(result, executingThread)
}

/** Suspends the execution of the current thread for the given duration.
*
* @param duration
Expand All @@ -218,6 +218,17 @@ object sus4s {
def delay(duration: Duration): Suspend ?=> Unit = {
Thread.sleep(duration.toMillis)
}

def race[A, B](firstBlock: Suspend ?=> A, secondBlock: Suspend ?=> B): Suspend ?=> A | B = ???

def race[A, B](firstBlock: Suspend ?=> A, secondBlock: Suspend ?=> B): Suspend ?=> A | B = {
val loomScope = new ShutdownOnSuccess[A | B]()
try {
loomScope.fork(() => { firstBlock })
loomScope.fork(() => { secondBlock })

loomScope.join()
loomScope.result(identity)
} finally {
loomScope.close()
}
}
}

0 comments on commit f3d8c6d

Please sign in to comment.