A reactor context handles 7 kinds of events :
Each event is processed immediately. The processing of non-reentrant events is followed by a succession of propagation turns until no more publishers are ready to emit, then a check for termination.
Publisher ordering is derived from the lexicographical ordering of their ranks, where the rank
of a publisher is the
sequence of birth ranks of its successive parents (root first), stored in an array. The birth rank is computed by
incrementing the field children
of the parent on each publisher spawning.
Stream backpressure is tracked with the publisher field pending
holding the number of subscriptions notified but not
yet transferred, +1 if active this turn. It is incremented on emission and for each subscription notification, and
decremented on end of active turn and for each subscription transfer. It is negative for signals (no backpressure).
A context schedules publishers ready to emit in two disjoint priority queues, for the current turn and the next one.
Both queues are represented as the root of a pairing heap,
or null
if the queue is empty, respectively in today
and tomorrow
. Each publisher stores its first child in
child
and its next older sibling in sibling
. When a publisher is removed from the heap, child
is assigned to
itself in order to efficiently check scheduling state.
Sets are needed for 3 purposes :
1 & 2 represent the set as a doubly-linked list. The set manager keeps references to the first and last item in head
and tail
(both null
if the set is empty), and the set items keep references to their predecessor and successor in
prev
and next
(null
respectively for the first and last items). When an item is removed, prev
is assigned to
itself in order to efficiently check set membership.
3 represents the set as a singly-linked list. The head of the list is stored in a local variable and the successor is
stored in field active
. When an item is inactive, active
is assigned to itself.
# Events A reactor context handles 7 kinds of events : 1. context boot 2. context cancellation 3. publisher notification 4. publisher termination 5. publisher cancellation 6. subscription transfer 7. subscription cancellation Each event is processed immediately. The processing of non-reentrant events is followed by a succession of propagation turns until no more publishers are ready to emit, then a check for termination. # Ordering Publisher ordering is derived from the lexicographical ordering of their ranks, where the `rank` of a publisher is the sequence of birth ranks of its successive parents (root first), stored in an array. The birth rank is computed by incrementing the field `children` of the parent on each publisher spawning. # Backpressure Stream backpressure is tracked with the publisher field `pending` holding the number of subscriptions notified but not yet transferred, +1 if active this turn. It is incremented on emission and for each subscription notification, and decremented on end of active turn and for each subscription transfer. It is negative for signals (no backpressure). # Priority queues A context schedules publishers ready to emit in two disjoint priority queues, for the current turn and the next one. Both queues are represented as the root of a [pairing heap](https://www.cs.cmu.edu/~sleator/papers/pairing-heaps.pdf), or `null` if the queue is empty, respectively in `today` and `tomorrow`. Each publisher stores its first child in `child` and its next older sibling in `sibling`. When a publisher is removed from the heap, `child` is assigned to itself in order to efficiently check scheduling state. # Sets Sets are needed for 3 purposes : 1. As long as a reactor is not cancelled, it maintains a set of cancellable publishers. 2. Between two successive emissions, a publisher maintains a set of notifiable subscriptions. 3. The set of emitting streams is maintained in order to deactivate them at the end of propagation turn. 1 & 2 represent the set as a doubly-linked list. The set manager keeps references to the first and last item in `head` and `tail` (both `null` if the set is empty), and the set items keep references to their predecessor and successor in `prev` and `next` (`null` respectively for the first and last items). When an item is removed, `prev` is assigned to itself in order to efficiently check set membership. 3 represents the set as a singly-linked list. The head of the list is stored in a local variable and the successor is stored in field `active`. When an item is inactive, `active` is assigned to itself.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close