Source code for m4us.interfaces

# -*- coding: utf-8 -*-

#---Header---------------------------------------------------------------------

# This file is part of Message For You Sir (m4us).
# Copyright © 2009-2012 Krys Lawrence
#
# Message For You Sir is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# Message For You Sir is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License
# for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Message For You Sir.  If not, see <http://www.gnu.org/licenses/>.


"""Provides the `interface` definitions for all important non-core objects."""

## pylint: disable=W0232


#---Imports--------------------------------------------------------------------

#---  Standard library imports
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
## pylint: disable=W0622, W0611
from future_builtins import ascii, filter, hex, map, oct, zip  ## NOQA
## pylint: enable=W0622, W0611

#---  Third-party imports
## pylint: disable=F0401
from zope import interface
## pylint: enable=F0401

#---  Project imports
from m4us.core import api as core


#---Globals--------------------------------------------------------------------


#---Functions------------------------------------------------------------------


#---Classes--------------------------------------------------------------------

#---  Concurrency interfaces

[docs]class IThreadedCoroutine(core.ICoroutine): """`Interface` that defines threaded `coroutines`. Threaded `coroutines` work just like regular `coroutines`, except they run in separate threads. This `interface` provides an additional method for explicitly starting the thread when it is appropriate. The advantage of running a threaded `coroutine` is that it's methods should return immediately allowing the main thread to continue running without blocking. The consequence of this, however, is that a `message` received from the `coroutine` is not necessarily the immediate response to the `message` that was sent in. That is, both sent and received `messages` are queued up in order and potentially processed at different rates. This is also true for thrown exceptions. """ ## pylint: disable=E0211
[docs] def start(): # pragma: no branch """Start the `coroutine` thread. :raises exceptions.RuntimeError: If the thread is already running. """ ## pylint: enable=E0211 #--- Backplanes interfaces
[docs]class IBackplaneFactory(core.ICoroutineFactory): """`Interface` for `callables` that return :class:`IBackplane` objects.""" ## pylint: disable=R0903 ## pylint: disable=E0211
[docs] def __call__(*args, **kwargs): # pragma: no branch """Return the desired `backplane`. :param collections.Sequence args: Any arguments to pass to the `factory` `callable`. :param collections.Mapping kwargs: Keywords arguments to pass to the `factory` `callable`. :returns: The desired `backplane` `coroutine` :rtype: :class:`IBackplane` """ ## pylint: enable=E0211 ## pylint: disable=R0903
[docs]class IBackplane(core.ICoroutine): """`Interface` that defines `backplane` `coroutines`. This is an analogue to Kamaelia_'s :class:`!Backplane`, and :class:`!SubscribeTo` components. A `backplane` is a `coroutine` to which one or more `publishers` can send `messages`, and to which one or more `subscribers` can then recieve those `messages`. The advantage of using a `backplane` is that the `subscribers` do not need to know about the `publishers` and vice versa. The only thing they each need to have is the `backplane` `coroutine` through which they are communicating. `Publishers` register themselves by sending an :class:`IRegisterPublisher` `message` to the `backplane`'s ``control`` `inbox`. Similarily, they unregister themselves by sending an :class:`IUnregisterPublisher` `message`. `Publishers` are expected to register before sending any `messages` and unregister before sending any :class:`~m4us.core.interfaces.IShutdown` `messages`. All this is needed so that the backplane knows when the last `publisher` is done and can wait until then to shutdown. `Subscribers` to a `backplane`, just need `link` to the `backplane`'s ``outbox`` and ``signal`` `outboxes` like any other `producer` `coroutine`. A `backplane` will shutdown upon reciept of an :class:`~m4us.core.interfaces.IShutdown` `message` on it's ``control`` `inbox`, but only when there are no registered `publishers` (i.e. they have all unregistered as part of their shutdown). It will also forward the shutdown `message` on to all `subscribers` on it's ``signal`` `outbox`, but again, only when there are no registered `publishers`. :raises m4us.backplanes.NotRegisteredError: If a `publisher` attempts to unregister itself without already being registered. :raises m4us.backplanes.AlreadyRegisteredError: If a `publisher` attempts to register itself more than once. .. _Kamaelia: http://www.kamaelia.org/ """ ## pylint: enable=R0903
[docs]class IRegisterPublisher(core.IMessage): """`Interface` for `messages` that register `publishers` with `backplanes`. :param publisher: `Messages` providing this `interface` should require a publishing object, specified as a keyword argument. .. seealso:: The :class:`IBackplane` `interface` for details about `messages` that use this `interface`. """ ## pylint: disable=R0903 publisher = interface.Attribute("""The `publisher` object to register.""")
[docs]class IUnregisterPublisher(core.IMessage): """`Interface` for `messages` that un-register `backplane` `publishers`. :param publisher: `Messages` providing this `interface` should require a publishing object, specified as a keyword argument. .. seealso:: The :class:`IBackplane` `interface` for details about `messages` that use this `interface`. """ ## pylint: disable=R0903 publisher = interface.Attribute( """The `publisher` object to un-register.""" ) #---Module initialization------------------------------------------------------ #---Late Imports--------------------------------------------------------------- #---Late Globals--------------------------------------------------------------- #---Late Functions------------------------------------------------------------- #---Late Classes--------------------------------------------------------------- #---Late Module initialization-------------------------------------------------