boing.core
— The pipeline infrastructure¶The module boing.core
contains all the classes that constitute
the infrastructure of Boing pipelines.
The Producer
and Consumer
classes are build over the
Observer design pattern of the module boing.core.observer
: the
Producer is an Observable object enabled to post products; a consumer
is an Observer object that can subscribe itself to many
producers. When a producer has a new product, it triggers the
registered consumers; the triggered consumers will immediately or at
regular time interval demand the producer the new products.
A Worker
object is both a Producer
and a
Consumer
and it is used as base class for defining processing
nodes. By connecting producers, workers and consumers it is possible
to create processing pipelines.
A WiseWorker
is a Worker
able to automatically
detect whenever it should not propose its own offer or its own
request; this is done in order to save computational time.
The Functor
class is practical base class for inheriting
custom processing Worker
objects. Instead of implementing the
classic Consumer._consume()
method, the Functor
proposes the more powerfull method Functor._process()
.
Multiple Producer
, Consumer
and Worker
instances can be composed into Composite
objects. There are
three types of composites:
CompositeProducer
works as it was a single producer;CompositeConsumer
works as it was a single consumer;CompositeWorker
works as it was a single worker;See also
boing.core.
Producer
(offer, tags=None, store=None, retrieve=None, haspending=None, parent=None)¶Producer
instances are Observable
objects able to post products to
a set of subscribed Consumer
instances. The argument
offer must be an instance of Offer
and it define the
products this producer will supply, while tags must be a dict or
None. The argument store can be a callable object to be used as a
handler for storing posted products (see _store()
for the
handler arguments) or None, while retrieve can be a callable
object to be used as a handler for retrieving stored products (see
_retrieveAndDeliver()
for the handler arguments) or
None. parent defines the consumer’s parent.
When a producer is demanded to posts a product, for each registered consumer it tests the product with the consumer’s request and only if the match is valid it triggers the consumer.
Public signals:
demandChanged
¶Signal emitted when the aggregate demand changes.
offerChanged
¶Signal emitted when its own offer changes.
demandedOfferChanged
¶Signal emitted when its own demanded offer changes.
Available methods:
aggregateDemand
()¶Return the union of all the subscribed consumers’ requests.
demandedOffer
()¶Return the producer’s demanded offer.
meetsRequest
()¶Return whether the product’s offer meets request.
offer
()¶Return the producer’s offer.
postProduct
(product)¶Post product. In concrete terms, it triggers the registered consumers that require product, then it stores the product.
boing.core.
Offer
(*args, iter=None)¶An Offer
defines the list of products that a producer
advertises to be its deliverable objects.
Note
A producer’s offer only estimates the products that are normally produced. There is no guarantee that such products will ever be posted, neither that products that do not match the offer won’t be produced.
Offer.UNDEFINED
can be used to define the producer’s
offer, when the real offer cannot be defined a priori. This avoids
to have empty offers, when they cannot be predeterminated.
boing.core.
Consumer
(request, consume=None, hz=None, parent=None)¶Consumer
objects are Observer
objects that can be subscribed to
several Producer
instances for receiving their
products. When a producer posts a product, it triggers the
registered consumers; then the consumers will immediately or at
regular time interval demand to the producer the new products.
Warning
Many consumers can be subscribed to a single producer. Each new product is actually shared within the different consumers, therefore a consumer MUST NOT modify any received product, unless it is supposed to be the only consumer.
Consumers have a Request
. When a producer is demanded to
posts a product, it tests the product with the consumer’s request
and only if the match is valid it triggers the consumer.
request
()¶Return the consumer’s request.
_consume
(products, producer)¶Consume the products posted from producer.
boing.core.
Request
¶The class Request
is an abstract class used by
Consumer
objects for specifing the set of products they
are insterested to. The method test()
is used to check
whether a product matches the request.
Request.NONE
and Request.ANY
define respectively
a “no product” and “any product” requests.
Request
objects may also indicate the
internal parts of a product to which a producer may be
interested. The method items()
returns the sequence of the
product’s parts a producer is interested to.
The class Request
implements the
design pattern “Composite”: different requests can be combined into
a single request by using the sum operation (e.g. comp =
r1 + r2
). A composite request matches the union of the products
that are matched by the requests whom it is
composed. Request.NONE
is the identity element of the sum
operation.
Request
objects are immutable.
test
(product)¶Return whether the product matches the request.
items
(product)¶Return an iterator over the product‘s internal parts (i.e. (key, value) pairs) that match the request.
boing.core.
Worker
¶A Worker
instance is both a Producer
and a
Consumer
. The class Worker
is by itself an
abstract class. Consider using the concrete class
BaseWorker
instead.
boing.core.
BaseWorker
(request, offer, tags=None, store=None, retrieve=None, haspending=None, consume=None, hz=None, parent=None)¶A BaseWorker
is the simplest concrete Worker
. By
default it does nothing with the products it receives, but it is
able to propagate the offers of the producers it is subscribed to,
and it is able to propagate the requests of the consumers that are
subscribed to it.
boing.core.
NopWorker
(store=None, retrieve=None, hz=None, parent=None)¶NopWorker
instances simply forwards all the products they
receive.
boing.core.
WiseWorker
(request, offer, **kwargs)¶A WiseWorker
instance is able to automatically detect
whenever it should not propose its own offer or its own request;
this is done in order to save computational time. The behaviour of
WiseWorker
objects works as follows:
A WiseWorker
is active (see method isActive()
) when
its own request is not deactivated (i.e. case 1).
A WiseWorker
can be forced to be activated or
deactivated. Use the method setForcing()
to impose a specific
behaviour.
Use WiseWorker.TUNNELING
as the worker Offer, when the
worker is supposed to process and then forward a subset of the
products it receives. This is necessary since sometimes it may be
possible that the worker cannot have a predefined offer since it
always depend from the offer of the observed producers.
isActive
()¶The WiseWorker
is active only if its offer is requested
from any subscribed consumer, unless it is forced (see
forcing()
).
isTunneling
()¶Return True if the worker is forwarding a subset of the products it receives.
forcing
()¶Return whether the WiseWorker is being forced. Return a value
within (WiseWorker.ACTIVATED
,
WiseWorker.DEACTIVATED
, WiseWorker.NONE
).
setForcing
(forcing)¶Impose to the WiseWorker
to be activated, deactivated
or remove a previous forcing. forcing must be a value within
(WiseWorker.ACTIVATED
, WiseWorker.DEACTIVATED
,
WiseWorker.NONE
).
ACTIVATED
¶Value used to force the WiseWorker
to be activated.
DEACTIVATED
¶Value used to force the WiseWorker
to be deactivated.
NONE
¶Value used to let the WiseWorker
decide it it should be
active.
TUNNELING
¶Value used to set the WiseWorker
the tunneling mode.
boing.core.
Functor
(args, offer, blender, process=None, **kwargs)¶The Functor
class is practical base class for inheriting
custom processing Workers
. Instead of implementing the
classic Consumer._consume()
method, the Functor
proposes the more powerfull method _process()
. This handler
method receives as argument sequence, an iterator over the
operands, which are iterators over the couples (key, value)
obtained from applying the method Request.items()
of the
request of the functor on the list of received products. This
enables to access directly to the name and values of the required
data without the need of reimplementing the code to get them. The
method _process()
is a generator method and it it supposed to
yield the the couples (key, value) representing the result of the
node processing. The yielded results are automatically considered
by the functor to create a new product that will be automatically
posted.
The functor uses a Functor.Blender
object to create the
new product. A set of predefined blenders are used to set the
functor behaviour:
Functor.MERGE
— Join the original product and results
of the functor.Functor.MERGECOPY
— Make a deep copy of the original
product and then join the results of the functor.Functor.RESULTONLY
— Post as product only the result of
the functor.A Functor
instance propagates the requests only if the
current blender is a MergeBlender
and it propagates the
offers only if the current blender is a MergeBlender
or if
it is tunneling (see WiseWorker.isTunneling()
).
blender
()¶Return the current active Functor.Blender
.
_process
(sequence, producer)¶This handler method receives as argument sequence, an iterator
over the operands, which are iterators over the couples (key,
value) obtained from applying the method Request.items()
of the request of the functor on the list of received
products. This enables to access directly to the name and values
of the required data without the need of reimplementing the code
to get them. This is a generator method and it it supposed to
yield the the couples (key, value) representing the result of
the node processing.
boing.core.
Composite
(*internals, parent=None)¶A Composite
instance stores a set of internal objects
using strong references. Use the method internals()
to scroll
the references objects.
internals
()¶Return an iterator over the set of internal nodes for which a strong reference is stored.
boing.core.
CompositeProducer
(*producers, internals=set(), parent=None)¶A CompositeProducer
combines in parallel the list of
producers so that they can be considered as a single
Producer
. The argument internals can be used to specify
the object for which a strong reference should be kept. All
producers are by default added as internals of the
Composite
.
producers
()¶Return an iterator over the first level producers.
boing.core.
CompositeConsumer
(*consumers, internals=set(), parent=None)¶A CompositeConsumer
combines in parallel the list of
consumers so that they can be considered as a single
Consumer
. The argument internals can be used to specify
the object for which a strong reference should be kept. All
consumers are by default added as internals of the
Composite
.
consumers
()¶Return an iterator over the first level consumers.
boing.core.
CompositeWorker
(consumers, producers, internals=set(), parent=None)¶A CompositeWorker
object combines in parallel the list of
producers and in parallel the list of consumers so that they
can be considered as a single Worker
. The argument
internals can be used to specify the object for which a strong
reference should be kept. All producers and consumers are by
default added as internals of the Composite
.