Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An asynchronous programming facility for Scala

License

NotificationsYou must be signed in to change notification settings

scala/scala-async

Repository files navigation

Supported Scala versions

This branch (version series 0.10.x) targets Scala 2.12 and 2.13.

Support for Scala 2.11 ison a branch.

Support for Scala 2.10 ison a branch.

Quick start

To include scala-async in an existing project use the library published on Maven Central.For sbt projects add the following to your build definition - build.sbt or project/Build.scala:

libraryDependencies+="org.scala-lang.modules"%%"scala-async"%"0.9.7"

For Maven projects add the following to your (make sure to use the correct Scala version suffixto match your project’s Scala binary version):

<dependency><groupId>org.scala-lang.modules</groupId><artifactId>scala-async_2.12</artifactId><version>0.10.0</version></dependency>

After adding a scala-async to your classpath, write your firstasync block:

importscala.concurrent.ExecutionContext.Implicits.globalimportscala.async.Async.{async,await}valfuture= async {valf1= async { ...;true }valf2= async { ...;42 }if (await(f1)) await(f2)else0}

What isasync?

async marks a block of asynchronous code. Such a block usually containsone or moreawait calls, which marks a point at which the computationwill be suspended until the awaitedFuture is complete.

By default,async blocks operate onscala.concurrent.{Future, Promise}.The system can be adapted to alternative implementations of theFuture pattern.

Consider the following example:

defslowCalcFuture:Future[Int]= ...// 01defcombined:Future[Int]= async {// 02  await(slowCalcFuture)+ await(slowCalcFuture)// 03}valx:Int=Await.result(combined,10.seconds)// 05

Line 1 defines an asynchronous method: it returns aFuture.

Line 2 begins anasync block. During compilation,the contents of this block will be analyzed to identifytheawait calls, and transformed into non-blockingcode.

Control flow will immediately pass to line 5, as thecomputation in theasync block is not executedon the caller's thread.

Line 3 begins by triggeringslowCalcFuture, and thensuspending until it has been calculated. Only after ithas finished, we trigger it again, and suspend again.Finally, we add the results and completecombined, whichin turn will release line 5 (unless it had already timed out).

It is important to note that while lines 1-4 are non-blocking,they are not parallel. If we wanted to parallelize the two computations,we could rearrange the code as follows:

defcombined:Future[Int]= async {valfuture1= slowCalcFuturevalfuture2= slowCalcFuture  await(future1)+ await(future2)}

Comparison with direct use ofFuture API

This computation could also be expressed by directly using thehigher-order functions of Futures:

defslowCalcFuture:Future[Int]= ...valfuture1= slowCalcFuturevalfuture2= slowCalcFuturedefcombined:Future[Int]=for {  r1<- future1  r2<- future2}yield r1+ r2

Theasync approach has two advantages over the use ofmap andflatMap:

  1. The code more directly reflects the programmer's intent,and does not require us to name the resultsr1 andr2.This advantage is even more pronounced when we mix controlstructures inasync blocks.
  2. async blocks are compiled to a single anonymous class,as opposed to a separate anonymous class for each closurerequired at each generator (<-) in the for-comprehension.This reduces the size of generated code, and can avoid boxingof intermediate results.

Comparison with CPS plugin

The existing continuations (CPS) plugin for Scala can also be usedto provide a syntactic layer likeasync. This approach has beenused in Akka'sDataflow Concurrency(now deprecated in favour of this library).

CPS-based rewriting of asynchronous code also produces a closurefor each suspension. It can also lead to type errors that aredifficult to understand.

How it works

  • Theasync macro analyses the block of code, looking for controlstructures and locations ofawait calls. It then breaks the codeinto 'chunks'. Each chunk contains a linear sequence of statementsthat concludes with a branching decision, or with the registrationof a subsequent state handler as the continuation.
  • Before this analysis and transformation, the program is normalizedinto a form amenable to this manipulation. This is called the"A Normal Form" (ANF), and roughly means that:
    • if andmatch constructs are only used as statements;they cannot be used as an expression.
    • calls toawait are not allowed in compound expressions.
  • Identify vals, vars and defs that are accessed from multiplestates. These will be lifted out to fields in the state machineobject.
  • Synthesize a class that holds:
    • an integer representing the current state ID.
    • the lifted definitions.
    • anapply(value: Try[Any]): Unit method that will becalled on completion of each future. The behavior ofthis method is determined by the current state. It recordsthe downcast result of the future in a field, and calls theresume() method.
    • theresume(): Unit method that switches on the current stateand runs the users code for one 'chunk', and either:a) registers the state machine as the handler for the next futureb) completes the result Promise of theasync block, if at the terminal state.
    • anapply(): Unit method that starts the computation.

Limitations

  • See theneg test casesfor constructs that are not allowed in anasync block.
  • See theissue list for which of these restrictions are plannedto be dropped in the future.
  • See#32 for whyawait is not possible in closures, and for suggestions onways to structure the code to work around this limitation.

About

An asynchronous programming facility for Scala

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors27

Languages


[8]ページ先頭

©2009-2025 Movatter.jp