gopher
package gopher
Provides scala API for 'go-like' CSP channels.
Overview
see readme for quick introduction.
Usage
At first you must receive gopherApi as Akka extension:
import gopher._ ..... val gopherApi = Gopher(actorSystem)
Then you can use CPS channels with blocling operations inside go clauses:
val channel = gopherApi.makeChannel[Long] val n = 10000 val producer = go { @volatile var(x,y) = (0L,1L) for( s <- gopherApi.select.forever) { case z: channel.write if (z==x) => x = y y = x+z if (x > n) { channel.close implicitly[FlowTermination[Unit]].doExit() } } } val consumer = for((c,i) <- channel.zip(1 to n)) { Console.println(s"fib(${i})=${c}") } Await.ready(consumer, 10 seconds)
and defer/recover in go/goScope
goScope{ val f = openFile(myFileName) defer{ if (! recover{case ex:FileNotFoundException => Console.println("invalid fname")}) { f.close() } } }
- See also
- Alphabetic
- By Inheritance
- gopher
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Type Members
-
class
ChannelClosedException
extends IllegalStateException
throwed when channel is closed:
throwed when channel is closed:
- during attempt to write to closed channel.
- during attempt to read from closed channel 'behind' last message.
-
class
Defers
[T] extends AnyRef
Construction Defers: defer/recover is alternative mechanism to exception handling, simular to one in Go language.
Construction Defers: defer/recover is alternative mechanism to exception handling, simular to one in Go language.
We use one hidden in go and goScope construct are transformed to withDefers usage with help of macroses.
It is also possible to use one unsugared (as in next example), but this is a bit verbose.
def parseCsv(fname: String): Either[String, Seq[Seq[Double]]] = withDefer[Either[String,Seq[Seq[Double]]]]{ d => val in = Source.fromFile(fname) d.defer{ var r = d.recover{ case FileNotFoundException => Left("fileNotFound") } if (!r) in.close() d.recover { case ex: Throwable => Left(ex.getMessage) } } val retval:Either[String,Seq[Seq[Double]]] = Right{ for( (line, nLine) <- in.getLines.toSeq zip Stream.from(1) ) yield withDefer[Seq[Double]] { d => line.split(",") map { s=> d.defer{ d.recover{ case ex: NumberFormatException => throw new RuntimeException(s"parse error in line ${nLine} file ${fname} ") } } s.toDouble } }.toSeq } retval }
-
trait
FlowTermination
[-A] extends AnyRef
FlowTermination[-A] - termination of flow.
FlowTermination[-A] - termination of flow.
Inside each block in select loop or select apply (once or forever) we have implicit FlowTermination entity, which we can use for exiting the loop.
select.forever{ case x: info.read => Console.println(s"received from info $x") case x: control.read => implicitly[FlowTermination[Unit]].doExit(()) }
-
implicit
class
FutureWithRead
[T] extends AnyRef
sugar for reading value from future.
-
class
GopherAPI
extends AnyRef
Api for providing access to channel and selector interfaces.
-
class
GopherImpl
extends GopherAPI with Extension
Akka extension which provide gopherApi interface
Akka extension which provide gopherApi interface
- See also
GopherAPI
- class ParTransputer extends Transputer
-
trait
SelectTransputer
extends ForeverSelectorBuilder with Transputer
Transputer, where dehaviour can be described by selector function
- sealed trait ThreadingPolicy extends AnyRef
-
trait
Transputer
extends AnyRef
Reusable unit of application structure, which consists from set of input ports, set of output ports and behaviour
Reusable unit of application structure, which consists from set of input ports, set of output ports and behaviour
Transputers can be created as elementary behaviour, descibed by select statement and then can be combined into larger structures
Transputers can be recovered from execeptions (i.e. transputer can be restarted or resume execution) or escalated to parent transputers or root superviser.
-
trait
TransputerLogging
extends AnyRef
mix this trait to ypu transputer for access to akka logging.
Value Members
- macro def asyncApply1[A, B, C](hof: ((A) ⇒ B) ⇒ C)(nf: (A) ⇒ Future[B]): Future[C]
- def awaitImpl[T](c: Context)(v: scala.reflect.macros.blackbox.Context.Expr[Future[T]]): scala.reflect.macros.blackbox.Context.Expr[T]
-
implicit
def
compileTimeFlowTermination[A]: FlowTermination[A]
- Annotations
- @compileTimeOnly( ... )
-
def
defer(x: ⇒ Unit): Unit
pseudostatement which can be used inside go/goScope block.
pseudostatement which can be used inside go/goScope block.
- Annotations
- @compileTimeOnly( ... )
-
macro
def
go[T](body: T)(implicit ec: ExecutionContext): Future[T]
starts asyncronics execution of
body
in provided execution context.starts asyncronics execution of
body
in provided execution context. Inside go we can usedefer
/recover
clauses and blocked read/write channel operations. -
macro
def
goScope[T](body: T): T
provide access to using defer/recover inside body in the current thread of execution.
-
def
recover[T](f: PartialFunction[Throwable, T]): Boolean
can be called only from defer block.
can be called only from defer block. If we in handling exception, try to apply
f
to exception and if it's applied - stop panic and return true, otherwise return false.- f
- partial function for recovering exception.
- returns
true if exception was recovered, false otherwise
- Annotations
- @compileTimeOnly( ... )
- implicit def toAsyncFullReadSelectorArgument[A, B](f: (ContRead[A, B]) ⇒ Option[(In[A]) ⇒ Future[Continuated[B]]]): ReadSelectorArgument[A, B]
- implicit def toAsyncFullSkipSelectorArgument[A](f: (Skip[A]) ⇒ Option[Future[Continuated[A]]]): SkipSelectorArgument[A]
- implicit def toAsyncFullWriteSelectorArgument[A, B](f: (ContWrite[A, B]) ⇒ Option[(A, Future[Continuated[B]])]): WriteSelectorArgument[A, B]
- implicit def toAsyncIterable[T](x: Iterable[T]): AsyncIterable[T]
- implicit def toAsyncNoGenReadSelectorArgument[A, B](f: (ContRead[A, B]) ⇒ (A) ⇒ Future[Continuated[B]]): ReadSelectorArgument[A, B]
- implicit def toAsyncNoOptSkipSelectorArgument[A](f: (Skip[A]) ⇒ Future[Continuated[A]]): SkipSelectorArgument[A]
- implicit def toAsyncNoOptWriteSelectorArgument[A, B](f: (ContWrite[A, B]) ⇒ (A, Future[Continuated[B]])): WriteSelectorArgument[A, B]
- implicit def toAsyncNoOptionReadSelectorArgument[A, B](f: (ContRead[A, B]) ⇒ (In[A]) ⇒ Future[Continuated[B]]): ReadSelectorArgument[A, B]
- implicit def toAsyncOption[T](x: Option[T]): AsyncOption[T]
- implicit def toAsyncPairReadSelectorArgument[A, B](f: (A, ContRead[A, B]) ⇒ Future[Continuated[B]]): ReadSelectorArgument[A, B]
- implicit def toSyncPairReadSelectorArgument[A, B](f: (A, ContRead[A, B]) ⇒ Continuated[B]): ReadSelectorArgument[A, B]
- implicit def toSyncReadSelectorArgument[A, B](f: (ContRead[A, B]) ⇒ (In[A]) ⇒ Continuated[B]): ReadSelectorArgument[A, B]
- implicit def toSyncSelectorArgument[A](f: (Skip[A]) ⇒ Continuated[A]): SkipSelectorArgument[A]
- implicit def toSyncWriteSelectorArgument[A, B](f: (ContWrite[A, B]) ⇒ (A, Continuated[B])): WriteSelectorArgument[A, B]
- object Defers
-
object
Gopher
extends ExtensionId[GopherImpl] with ExtensionIdProvider
Factory object for Akka extension
Factory object for Akka extension
val actorSystem = ActorSystem("myapp") val gopherApi = Gopher(actorSystem)
- object GopherAPI
- object GopherAPIExtensionHelper
- object ThreadingPolicy
- object Transputer
-
object
withDefer
syntax sugar, for calling Defers.