Channel
is a shareable reference to a writing endpoint of a reactor.
Channel
is a shareable reference to a writing endpoint of a reactor.
By calling the channel's !
method, an event is sent to the channel. The event is
eventually emitted on the channel's corresponding event stream, which is readable
only by the reactor that owns that channel.
type of the events propagated by this channel
Used for building channel objects.
A pair of a channel and its event stream.
A pair of a channel and its event stream.
Allows closing the channel with its seal
operation.
Debugger interface for the reactor system.
The default handler prints the exception to the standard error stream.
Class that describes error handlers that report uncaught reactor-level exceptions.
An event buffer that is simultaneously an event stream.
An event buffer that is simultaneously an event stream.
Events are stored into the buffer with the enqueue
method.
Events are dequeued and simultaneously emitted with the dequeue
method.
Calling unsubscribe
unreacts.
Note: this class can only be used inside a single reactor, and is not meant to be shared across multiple threads.
type of the events in this event stream
A queue that buffers events that arrive on the corresponding channel.
A queue that buffers events that arrive on the corresponding channel.
The enqueue
method may have FIFO queue, priority queue, or some other semantics,
depending on the implementation.
A basic event stream.
A basic event stream.
Event streams are special objects that may produce events of a certain type T
.
Clients may subscribe side-effecting functions (i.e. callbacks)
to these events with onReaction
, onEvent
, onMatch
and on
--
each of these methods will invoke the callback when an event
is produced, but some may be more suitable depending on the use-case.
An event stream produces events until it unreacts. After the event stream unreacts, it never produces an event again.
Event streams can also be manipulated using declarative combinators
such as map
, filter
, until
, after
and scanPast
:
def positiveSquares(r: Events[Int]) = r.map(x => x * x).filter(_ != 0)
With the exception of onX
family of methods, and unless otherwise specified,
operators passed to these declarative combinators should be pure -- they should not
have any side-effects.
The result of applying a declarative combinator on Events[T]
is usually
another Events[S]
, possibly with a type parameter S
different from T
.
Event sink combinators, such as onEvent
, return a Subscription
object used to
unsubscribe
from their event source.
Combinators that start with the prefix on
, to
, pipe
or get
are called *sink
combinators*. Calling these combinators subscribes to the event stream and creates
a subscription object. The event source is from there on responsible for propagating
events to sink combinators until it either *unreacts*, meaning that it will not
emit any other events, or the event sink gets *unsubscribed*. The event sink can be
unsubscribed by calling the unsubscribe
method of the Subscription
object.
The client is responsible for unsubscribing from an event source once the events are
no longer needed. Failure to do so risks *time leaks*, a form of resource leak in
which the program gets slower and slower (because it needs to propagate no longer
needed events).
Event streams are specialized for Int
, Long
and Double
.
Every event stream is bound to a specific Reactor
, the basic unit of concurrency.
Within a reactor, at most a single event stream propagates events at a time.
An event stream will only produce events during the execution of that reactor --
events are never triggered on a different reactor.
It is forbidden to share event streams between reactors.
type of the events in this event stream
An event stream that can be either completed, or unreacted at most once.
An event stream that can be either completed, or unreacted at most once.
Assigning a value propagates an event to all the subscribers, and then propagates an unreaction. To assign a value:
val iv = new Events.IVar[Int] iv := 5 assert(iv() == 5)
To unreact (i.e. seal, or close) an ivar without assigning a value:
val iv = new Events.IVar[Int] iv.unreact() assert(iv.isUnreacted)
type of the value in the IVar
Any object that contains a unique id within some scope.
An object that can act upon an event or be signalled that there will be no more events.
An object that can act upon an event or be signalled that there will be no more events.
type of events the observer responds to
A prototype for instantiating a reactor that takes specific parameters.
A prototype for instantiating a reactor that takes specific parameters.
type of the reactor
An encapsulation of a set of event streams and channels.
The reactive cell abstraction represents a mutable memory location whose changes may produce events.
The reactive cell abstraction represents a mutable memory location whose changes may produce events.
An RCell
is conceptually similar to a reactive emitter lifted into a signal.
An RCell
can be created full, or empty. If empty, retrieving its value throws
an exception. Once assigned, the RCell
is no longer empty, until clear
gets
called.
the type of the values it stores
A reactor is a basic unit of concurrency.
A reactor is a basic unit of concurrency.
A concurrent program in the Reactors framework is composed of multiple reactors, which execute concurrently, and in isolation. The only way they can communicate is by exchanging events using entities called *channels*.
A Reactor[T]
object accepts events of type T
on its input channel.
One reactor can propagate events concurrently to other reactors.
Event streams cannot be shared between reactors --
it is an error to use an event stream originating in one reactor
in some different reactor.
Reactors are defined by extending the Reactor
trait.
The events passed to reactors can be subscribed to using
their main.events
stream.
Here is an example:
class MyPrinter extends Reactor[String] { main.events onEvent { e => println(e) } }
Separate reactor instances that exist at runtime are created using reactor systems. Each reactor belongs to a specific reactor system. Usually there is a single reactor system within a single program instance. Here is an example:
val reactorSystem = ReactorSystem.default("MyReactorSystem") val channel = reactorSystem.spawn(Proto[MyPrinter])
Creating a reactor returns its channel.
Events can be sent to a channel using the !
method:
channel ! "Hi!" // eventually, this is printed by `MyPrinter`
To stop, a reactor must seal its main channel. The following reactor seals its main channel after receiving the first event:
class MyPrinter extends Reactor[String] { main.events onEvent { e => println(e) main.seal() } }
Reactors also receive special SysEvent
events on the sysEvents
stream.
the type of events, which this
reactor produces
Denotes that the reactor died due to an exception.
Denotes that the reactor died due to an exception.
This event is sent after ReactorStarted
.
This event is sent before ReactorTerminated
, *unless* the exception is thrown
while ReactorTerminated
is being processed, in which case the ReactorDied
is
not sent.
Note that, if the exception is thrown during the reactor constructor invocation and before the appropriate event handler is created, this event cannot be sent to that event handler.
the exception that the reactor threw
Thrown when an error in reactor execution occurs.
A system used to create, track and identify reactors.
A system used to create, track and identify reactors.
A reactor system is composed of a set of reactors that have a common configuration.
Service that tracks different transports for remote communication.
Service that tracks different transports for remote communication.
The most important method is resolve
, which creates a channel from a
channel URL. This allows communication with reactors in non-local
reactor systems, e.g. in another process, or on another machine.
An object that schedules reactors for execution.
An object that schedules reactors for execution.
After a reactor is instantiated, its reactor frame is assigned a scheduler by the reactor system. A reactor that is assigned a specific scheduler will always be executed on that same scheduler.
After creating a reactor, every reactor system will first call the initSchedule
method on the reactor frame.
Then, the reactor system will call the schedule
method every time there are events
ready for the reactor.
Note:
Clients never invoke Scheduler
operations directly,
but can implement their own scheduler if necessary.
org.reactors.ReactorSystem
A special type of an event stream that caches the last emitted event.
A special type of an event stream that caches the last emitted event.
This last event is called the signal's value.
It can be read using the Signal
's apply
method.
the type of the events in this signal
Silent handler ignores exceptions.
Evidence value for specialized type parameters.
Evidence value for specialized type parameters.
Used to artificially insert the type into a type signature.
A subscription to a certain kind of event, event processing or computation.
A subscription to a certain kind of event, event processing or computation.
Calling unsubscribe
on the subscription causes the events to no longer be
propagated to this subscription, or some computation to cease.
Unsubscribing is idempotent -- calling unsubscribe
second time does nothing.
System events are a special kind of internal events that can be observed by reactors.
Thrown when an exception is propagated to an event handler, such as onEvent
.
Default channel implementations.
Contains default event queue implementations.
Contains useful Events
implementations and factory methods.
Matches lethal throwables.
Matches non-lethal throwables.
Denotes that the reactor was preempted by the scheduler.
Denotes that the reactor was preempted by the scheduler.
Always sent after ReactorStarted
and before ReactorTerminated
.
When the reactor is preempted, it loses control of the execution thread, until the scheduler schedules it again on some (possibly the same) thread. This event is typically used to send another message back to the reactor, indicating that he should be scheduled again later.
Denotes that the reactor was scheduled for execution by the scheduler.
Denotes that the reactor was scheduled for execution by the scheduler.
Always sent after ReactorStarted
and before ReactorTerminated
.
This event usually occurs when reactor is woken up to process incoming events, but may be invoked even if there are no pending events. This event is typically used in conjunction with a scheduler that periodically wakes up the reactor.
Denotes start of a reactor.
Denotes start of a reactor.
Produced before any other event.
Contains factory methods for creating reactor systems.
Denotes the termination of a reactor.
Denotes the termination of a reactor.
Called after all other events.
Types and methods related to the Remote
service.
Companion object for creating standard reactor schedulers.
Default subscription implementations.
Partial function ignores non-lethal throwables.
Partial function ignores non-lethal throwables.
This is useful in composition with other exception handlers.
Determines if the throwable is lethal, i.e.
Determines if the throwable is lethal, i.e. should the program immediately stop.
Determines if the throwable is not lethal.