Rename to slixmpp
[slixmpp.git] / docs / architecture.rst
blob52bb8d9c5feb9e8436026392bfdbab5413953f76
1 .. index:: XMLStream, BaseXMPP, ClientXMPP, ComponentXMPP
3 Slixmpp Architecture
4 ======================
6 The core of Slixmpp is contained in four classes: ``XMLStream``,
7 ``BaseXMPP``, ``ClientXMPP``, and ``ComponentXMPP``. Along side this
8 stack is a library for working with XML objects that eliminates most
9 of the tedium of creating/manipulating XML.
11 .. image:: _static/images/arch_layers.png
12     :height: 300px
13     :align: center
16 .. index:: XMLStream
18 The Foundation: XMLStream
19 -------------------------
20 :class:`~slixmpp.xmlstream.xmlstream.XMLStream` is a mostly XMPP-agnostic
21 class whose purpose is to read and write from a bi-directional XML stream.
22 It also allows for callback functions to execute when XML matching given
23 patterns is received; these callbacks are also referred to as :term:`stream
24 handlers <stream handler>`. The class also provides a basic eventing system
25 which can be triggered either manually or on a timed schedule.
27 The Main Threads
28 ~~~~~~~~~~~~~~~~
29 :class:`~slixmpp.xmlstream.xmlstream.XMLStream` instances run using at
30 least three background threads: the send thread, the read thread, and the
31 scheduler thread. The send thread is in charge of monitoring the send queue
32 and writing text to the outgoing XML stream. The read thread pulls text off
33 of the incoming XML stream and stores the results in an event queue. The
34 scheduler thread is used to emit events after a given period of time.
36 Additionally, the main event processing loop may be executed in its
37 own thread if Slixmpp is being used in the background for another
38 application.
40 Short-lived threads may also be spawned as requested for threaded
41 :term:`event handlers <event handler>`.
43 How XML Text is Turned into Action
44 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 To demonstrate the flow of information, let's consider what happens
46 when this bit of XML is received (with an assumed namespace of
47 ``jabber:client``):
49 .. code-block:: xml
51     <message to="user@example.com" from="friend@example.net">
52       <body>Hej!</body>
53     </message>
56 1. **Convert XML strings into objects.**
58    Incoming text is parsed and converted into XML objects (using
59    ElementTree) which are then wrapped into what are referred to as
60    :term:`Stanza objects <stanza object>`. The appropriate class for the
61    new object is determined using a map of namespaced element names to
62    classes.
64    Our incoming XML is thus turned into a :class:`~slixmpp.stanza.Message`
65    :term:`stanza object` because the namespaced element name
66    ``{jabber:client}message`` is associated with the class
67    :class:`~slixmpp.stanza.Message`.
69 2. **Match stanza objects to callbacks.**
71    These objects are then compared against the stored patterns associated
72    with the registered callback handlers. For each match, a copy of the
73    :term:`stanza object` is paired with a reference to the handler and
74    placed into the event queue.
76    Our :class:`~slixmpp.stanza.Message` object is thus paired with the message stanza handler
77    :meth:`BaseXMPP._handle_message` to create the tuple::
79        ('stanza', stanza_obj, handler)
81 3. **Process the event queue.**
83    The event queue is the heart of Slixmpp. Nearly every action that
84    takes place is first inserted into this queue, whether that be received
85    stanzas, custom events, or scheduled events.
87    When the stanza is pulled out of the event queue with an associated
88    callback, the callback function is executed with the stanza as its only
89    parameter.
91    .. warning:: 
92        The callback, aka :term:`stream handler`, is executed in the main event
93        processing thread. If the handler blocks, event processing will also
94        block.
96 4. **Raise Custom Events**
98    Since a :term:`stream handler` shouldn't block, if extensive processing
99    for a stanza is required (such as needing to send and receive an
100    :class:`~slixmpp.stanza.Iq` stanza), then custom events must be used.
101    These events are not explicitly tied to the incoming XML stream and may
102    be raised at any time. Importantly, these events may be handled in their
103    own thread.
105    When the event is raised, a copy of the stanza is created for each
106    handler registered for the event. In contrast to :term:`stream handlers
107    <stream handler>`, these functions are referred to as :term:`event
108    handlers <event handler>`. Each stanza/handler pair is then put into the
109    event queue.
111    .. note::
112        It is possible to skip the event queue and process an event immediately
113        by using ``direct=True`` when raising the event.
115    The code for :meth:`BaseXMPP._handle_message` follows this pattern, and
116    raises a ``'message'`` event::
118        self.event('message', msg)
120    The event call then places the message object back into the event queue
121    paired with an :term:`event handler`::
123        ('event', 'message', msg_copy1, custom_event_handler_1)
124        ('event', 'message', msg_copy2, custom_evetn_handler_2) 
126 5. **Process Custom Events**
128    The stanza and :term:`event handler` are then pulled from the event
129    queue, and the handler is executed, passing the stanza as its only
130    argument. If the handler was registered as threaded, then a new thread
131    will be spawned for it.
133    .. note::
134        Events may be raised without needing :term:`stanza objects <stanza object>`. 
135        For example, you could use ``self.event('custom', {'a': 'b'})``. 
136        You don't even need any arguments: ``self.event('no_parameters')``. 
137        However, every event handler MUST accept at least one argument.
139    Finally, after a long trek, our message is handed off to the user's
140    custom handler in order to do awesome stuff::
142        msg.reply()
143        msg['body'] = "Hey! This is awesome!"
144        msg.send()
147 .. index:: BaseXMPP, XMLStream
149 Raising XMPP Awareness: BaseXMPP
150 --------------------------------
151 While :class:`~slixmpp.xmlstream.xmlstream.XMLStream` attempts to shy away
152 from anything too XMPP specific, :class:`~slixmpp.basexmpp.BaseXMPP`'s
153 sole purpose is to provide foundational support for sending and receiving
154 XMPP stanzas. This support includes registering the basic message,
155 presence, and iq stanzas, methods for creating and sending stanzas, and
156 default handlers for incoming messages and keeping track of presence
157 notifications.
159 The plugin system for adding new XEP support is also maintained by
160 :class:`~slixmpp.basexmpp.BaseXMPP`.
162 .. index:: ClientXMPP, BaseXMPP
164 ClientXMPP
165 ----------
166 :class:`~slixmpp.clientxmpp.ClientXMPP` extends
167 :class:`~slixmpp.clientxmpp.BaseXMPP` with additional logic for connecting
168 to an XMPP server by performing DNS lookups. It also adds support for stream
169 features such as STARTTLS and SASL.
171 .. index:: ComponentXMPP, BaseXMPP
173 ComponentXMPP
174 -------------
175 :class:`~slixmpp.componentxmpp.ComponentXMPP` is only a thin layer on top of
176 :class:`~slixmpp.basexmpp.BaseXMPP` that implements the component handshake
177 protocol.