diff options
Diffstat (limited to 'qpid/doc/book/src/QMF-Python-Console-Tutorial.xml')
-rw-r--r-- | qpid/doc/book/src/QMF-Python-Console-Tutorial.xml | 894 |
1 files changed, 894 insertions, 0 deletions
diff --git a/qpid/doc/book/src/QMF-Python-Console-Tutorial.xml b/qpid/doc/book/src/QMF-Python-Console-Tutorial.xml new file mode 100644 index 0000000000..2cb802671b --- /dev/null +++ b/qpid/doc/book/src/QMF-Python-Console-Tutorial.xml @@ -0,0 +1,894 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> + +<section><title> + QMF Python Console Tutorial + </title> + <itemizedlist> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-PrerequisiteInstallQpidMessaging"/> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-SynchronousConsoleOperations"/> + </para></listitem> + <listitem><para> + <itemizedlist> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-CreatingaQMFConsoleSessionandAttachingtoaBroker"/> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-AccessingManagedObjects"/> + </para></listitem> + <listitem><para> + <itemizedlist> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-ViewingPropertiesandStatisticsofanObject"/> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-InvokingMethodsonanObject"/> + </para></listitem> + </itemizedlist> + </para></listitem> + </itemizedlist> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-AsynchronousConsoleOperations"/> + </para></listitem> + <listitem><para> + <itemizedlist> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-CreatingaConsoleClasstoReceiveAsynchronousData"/> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-ReceivingEvents"/> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-ReceivingObjects"/> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-AsynchronousMethodCallsandMethodTimeouts"/> + </para></listitem> + </itemizedlist> + </para></listitem> + <listitem><para> + <xref linkend="QMFPythonConsoleTutorial-DiscoveringwhatKindsofObjectsareAvailable"/> + </para></listitem> + </itemizedlist> + <section role="h1" id="QMFPythonConsoleTutorial-PrerequisiteInstallQpidMessaging"><title> + Prerequisite + - Install Qpid Messaging + </title> + + <para> + QMF uses AMQP Messaging (QPid) as its means of communication. To + use QMF, Qpid messaging must be installed somewhere in the + network. Qpid can be downloaded as source from Apache, is + packaged with a number of Linux distributions, and can be + purchased from commercial vendors that use Qpid. Please see + <ulink url="http://qpid.apache.org">http://qpid.apache.org</ulink>for + information as to where to get Qpid Messaging. + </para><para> + Qpid Messaging includes a message broker (qpidd) which typically + runs as a daemon on a system. It also includes client bindings in + various programming languages. The Python-language client library + includes the QMF console libraries needed for this tutorial. + </para><para> + Please note that Qpid Messaging has two broker implementations. + One is implemented in C++ and the other in Java. At press time, + QMF is supported only by the C++ broker. + </para><para> + If the goal is to get the tutorial examples up and running as + quickly as possible, all of the Qpid components can be installed + on a single system (even a laptop). For more realistic + deployments, the broker can be deployed on a server and the + client/QMF libraries installed on other systems. + </para> +<!--h1--></section> + + <section role="h1" id="QMFPythonConsoleTutorial-SynchronousConsoleOperations"><title> + Synchronous + Console Operations + </title> + + <para> + The Python console API for QMF can be used in a synchronous + style, an asynchronous style, or a combination of both. + Synchronous operations are conceptually simple and are well + suited for user-interactive tasks. All operations are performed + in the context of a Python function call. If communication over + the message bus is required to complete an operation, the + function call blocks and waits for the expected result (or + timeout failure) before returning control to the caller. + </para><section role="h2" id="QMFPythonConsoleTutorial-CreatingaQMFConsoleSessionandAttachingtoaBroker"><title> + Creating a QMF Console Session and Attaching to a Broker + </title> + + <para> + For the purposes of this tutorial, code examples will be shown as + they are entered in an interactive python session. + </para> + <programlisting> +$ python +Python 2.5.2 (r252:60911, Sep 30 2008, 15:41:38) +[GCC 4.3.2 20080917 (Red Hat 4.3.2-4)] on linux2 +Type "help", "copyright", "credits" or "license" for more information. +>>> +</programlisting> + <para> + We will begin by importing the required libraries. If the Python + client is properly installed, these libraries will be found + normally by the Python interpreter. + </para> + <programlisting> +>>> from qmf.console import Session +</programlisting> + <para> + We must now create a <emphasis>Session</emphasis> object to manage this QMF + console session. + </para> + <programlisting> +>>> sess = Session() +</programlisting> + <para> + If no arguments are supplied to the creation of <emphasis>Session</emphasis>, + it defaults to synchronous-only operation. It also defaults to + user-management of connections. More on this in a moment. + </para><para> + We will now establish a connection to the messaging broker. If + the broker daemon is running on the local host, simply use the + following: + </para> + <programlisting> +>>> broker = sess.addBroker() +</programlisting> + <para> + If the messaging broker is on a remote host, supply the URL to + the broker in the <emphasis>addBroker</emphasis> function call. Here's how to + connect to a local broker using the URL. + </para> + <programlisting> +>>> broker = sess.addBroker("amqp://localhost") +</programlisting> + <para> + The call to <emphasis>addBroker</emphasis> is synchronous and will return + only after the connection has been successfully established or + has failed. If a failure occurs, <emphasis>addBroker</emphasis> will raise an + exception that can be handled by the console script. + </para> + <programlisting> +>>> try: +... broker = sess.addBroker("amqp://localhost:1000") +... except: +... print "Connection Failed" +... +Connection Failed +>>> +</programlisting> + <para> + This operation fails because there is no Qpid Messaging broker + listening on port 1000 (the default port for qpidd is 5672). + </para><para> + If preferred, the QMF session can manage the connection for you. + In this case, <emphasis>addBroker</emphasis> returns immediately and the + session attempts to establish the connection in the background. + This will be covered in detail in the section on asynchronous + operations. + </para> +<!--h2--></section> + + <section role="h2" id="QMFPythonConsoleTutorial-AccessingManagedObjects"><title> + Accessing + Managed Objects + </title> + + <para> + The Python console API provides access to remotely managed + objects via a <emphasis>proxy</emphasis> model. The API gives the client an + object that serves as a proxy representing the "real" object + being managed on the agent application. Operations performed on + the proxy result in the same operations on the real object. + </para><para> + The following examples assume prior knowledge of the kinds of + objects that are actually available to be managed. There is a + section later in this tutorial that describes how to discover + what is manageable on the QMF bus. + </para><para> + Proxy objects are obtained by calling the + <emphasis>Session.getObjects</emphasis> function. + </para><para> + To illustrate, we'll get a list of objects representing queues in + the message broker itself. + </para> + <programlisting> +>>> queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker") +</programlisting> + <para> + <emphasis>queues</emphasis> is an array of proxy objects representing real + queues on the message broker. A proxy object can be printed to + display a description of the object. + </para> + <programlisting> +>>> for q in queues: +... print q +... +org.apache.qpid.broker:queue[0-1537-1-0-58] 0-0-1-0-1152921504606846979:reply-localhost.localdomain.32004 +org.apache.qpid.broker:queue[0-1537-1-0-61] 0-0-1-0-1152921504606846979:topic-localhost.localdomain.32004 +>>> +</programlisting> + <section role="h3" id="QMFPythonConsoleTutorial-ViewingPropertiesandStatisticsofanObject"><title> + Viewing Properties and Statistics of an Object + </title> + + <para> + Let us now focus our attention on one of the queue objects. + </para> + <programlisting> +>>> queue = queues[0] +</programlisting> + <para> + The attributes of an object are partitioned into + <emphasis>properties</emphasis> and <emphasis>statistics</emphasis>. Though the + distinction is somewhat arbitrary, <emphasis>properties</emphasis> tend to + be fairly static and may also be large and <emphasis>statistics</emphasis> + tend to change rapidly and are relatively small (counters, etc.). + </para><para> + There are two ways to view the properties of an object. An array + of properties can be obtained using the <emphasis>getProperties</emphasis> + function: + </para> + <programlisting> +>>> props = queue.getProperties() +>>> for prop in props: +... print prop +... +(vhostRef, 0-0-1-0-1152921504606846979) +(name, u'reply-localhost.localdomain.32004') +(durable, False) +(autoDelete, True) +(exclusive, True) +(arguments, {}) +>>> +</programlisting> + <para> + The <emphasis>getProperties</emphasis> function returns an array of tuples. + Each tuple consists of the property descriptor and the property + value. + </para><para> + A more convenient way to access properties is by using the + attribute of the proxy object directly: + </para> + <programlisting> +>>> queue.autoDelete +True +>>> queue.name +u'reply-localhost.localdomain.32004' +>>> +</programlisting> + <para> + Statistics are accessed in the same way: + </para> + <programlisting> +>>> stats = queue.getStatistics() +>>> for stat in stats: +... print stat +... +(msgTotalEnqueues, 53) +(msgTotalDequeues, 53) +(msgTxnEnqueues, 0) +(msgTxnDequeues, 0) +(msgPersistEnqueues, 0) +(msgPersistDequeues, 0) +(msgDepth, 0) +(byteDepth, 0) +(byteTotalEnqueues, 19116) +(byteTotalDequeues, 19116) +(byteTxnEnqueues, 0) +(byteTxnDequeues, 0) +(bytePersistEnqueues, 0) +(bytePersistDequeues, 0) +(consumerCount, 1) +(consumerCountHigh, 1) +(consumerCountLow, 1) +(bindingCount, 2) +(bindingCountHigh, 2) +(bindingCountLow, 2) +(unackedMessages, 0) +(unackedMessagesHigh, 0) +(unackedMessagesLow, 0) +(messageLatencySamples, 0) +(messageLatencyMin, 0) +(messageLatencyMax, 0) +(messageLatencyAverage, 0) +>>> +</programlisting> + <para> + or alternatively: + </para> + <programlisting> +>>> queue.byteTotalEnqueues +19116 +>>> +</programlisting> + <para> + The proxy objects do not automatically track changes that occur + on the real objects. For example, if the real queue enqueues more + bytes, viewing the <emphasis>byteTotalEnqueues</emphasis> statistic will show + the same number as it did the first time. To get updated data on + a proxy object, use the <emphasis>update</emphasis> function call: + </para> + <programlisting> +>>> queue.update() +>>> queue.byteTotalEnqueues +19783 +>>> +</programlisting> + + <note><title>Be Advised</title> + <para> + The <emphasis>update</emphasis> method was added after the M4 release + of Qpid/Qmf. It may not be available in your + distribution. + </para> + </note> +<!--h3--></section> + + <section role="h3" id="QMFPythonConsoleTutorial-InvokingMethodsonanObject"><title> + Invoking + Methods on an Object + </title> + + <para> + Up to this point, we have used the QMF Console API to find + managed objects and view their attributes, a read-only activity. + The next topic to illustrate is how to invoke a method on a + managed object. Methods allow consoles to control the managed + agents by either triggering a one-time action or by changing the + values of attributes in an object. + </para><para> + First, we'll cover some background information about methods. A + <emphasis>QMF object class</emphasis> (of which a <emphasis>QMF object</emphasis> is an + instance), may have zero or more methods. To obtain a list of + methods available for an object, use the <emphasis>getMethods</emphasis> + function. + </para> + <programlisting> +>>> methodList = queue.getMethods() +</programlisting> + <para> + <emphasis>getMethods</emphasis> returns an array of method descriptors (of + type qmf.console.SchemaMethod). To get a summary of a method, you + can simply print it. The _<emphasis>repr</emphasis>_ function returns a + string that looks like a function prototype. + </para> + <programlisting> +>>> print methodList +[purge(request)] +>>> +</programlisting> + <para> + For the purposes of illustration, we'll use a more interesting + method available on the <emphasis>broker</emphasis> object which represents + the connected Qpid message broker. + </para> + <programlisting> +>>> br = sess.getObjects(_class="broker", _package="org.apache.qpid.broker")[0] +>>> mlist = br.getMethods() +>>> for m in mlist: +... print m +... +echo(sequence, body) +connect(host, port, durable, authMechanism, username, password, transport) +queueMoveMessages(srcQueue, destQueue, qty) +>>> +</programlisting> + <para> + We have just learned that the <emphasis>broker</emphasis> object has three + methods: <emphasis>echo</emphasis>, <emphasis>connect</emphasis>, and + <emphasis>queueMoveMessages</emphasis>. We'll use the <emphasis>echo</emphasis> method to + "ping" the broker. + </para> + <programlisting> +>>> result = br.echo(1, "Message Body") +>>> print result +OK (0) - {'body': u'Message Body', 'sequence': 1} +>>> print result.status +0 +>>> print result.text +OK +>>> print result.outArgs +{'body': u'Message Body', 'sequence': 1} +>>> +</programlisting> + <para> + In the above example, we have invoked the <emphasis>echo</emphasis> method on + the instance of the broker designated by the proxy "br" with a + sequence argument of 1 and a body argument of "Message Body". The + result indicates success and contains the output arguments (in + this case copies of the input arguments). + </para><para> + To be more precise... Calling <emphasis>echo</emphasis> on the proxy causes + the input arguments to be marshalled and sent to the remote agent + where the method is executed. Once the method execution + completes, the output arguments are marshalled and sent back to + the console to be stored in the method result. + </para><para> + You are probably wondering how you are supposed to know what + types the arguments are and which arguments are input, which are + output, or which are both. This will be addressed later in the + "Discovering what Kinds of Objects are Available" section. + </para> +<!--h3--></section> +<!--h2--></section> +<!--h1--></section> + + <section role="h1" id="QMFPythonConsoleTutorial-AsynchronousConsoleOperations"><title> + Asynchronous + Console Operations + </title> + + <para> + QMF is built on top of a middleware messaging layer (Qpid + Messaging). Because of this, QMF can use some communication + patterns that are difficult to implement using network transports + like UDP, TCP, or SSL. One of these patterns is called the + <emphasis>Publication and Subscription</emphasis> pattern (pub-sub for + short). In the pub-sub pattern, data sources <emphasis>publish</emphasis> + information without a particular destination in mind. Data sinks + (destinations) <emphasis>subscribe</emphasis> using a set of criteria that + describes what kind of data they are interested in receiving. + Data published by a source may be received by zero, one, or many + subscribers. + </para><para> + QMF uses the pub-sub pattern to distribute events, object + creation and deletion, and changes to properties and statistics. + A console application using the QMF Console API can receive these + asynchronous and unsolicited events and updates. This is useful + for applications that store and analyze events and/or statistics. + It is also useful for applications that react to certain events + or conditions. + </para><para> + Note that console applications may always use the synchronous + mechanisms. + </para> + + <section role="h2" id="QMFPythonConsoleTutorial-CreatingaConsoleClasstoReceiveAsynchronousData"><title> + Creating a Console Class to Receive Asynchronous Data + </title> + + <para> + Asynchronous API operation occurs when the console application + supplies a <emphasis>Console</emphasis> object to the session manager. The + <emphasis>Console</emphasis> object (which overrides the + <emphasis>qmf.console.Console</emphasis> class) handles all asynchronously + arriving data. The <emphasis>Console</emphasis> class has the following + methods. Any number of these methods may be overridden by the + console application. Any method that is not overridden defaults + to a null handler which takes no action when invoked. + </para><table><title>QMF Python Console Class Methods</title><tgroup cols="3"> + <tbody> + <row> + <entry> + Method + </entry> + <entry> + Arguments + </entry> + <entry> + Invoked when... + </entry> + </row> + <row> + <entry> + brokerConnected + </entry> + <entry> + broker + </entry> + <entry> + a connection to a broker is established + </entry> + </row> + <row> + <entry> + brokerDisconnected + </entry> + <entry> + broker + </entry> + <entry> + a connection to a broker is lost + </entry> + </row> + <row> + <entry> + newPackage + </entry> + <entry> + name + </entry> + <entry> + a new package is seen on the QMF bus + </entry> + </row> + <row> + <entry> + newClass + </entry> + <entry> + kind, classKey + </entry> + <entry> + a new class (event or object) is seen on the QMF bus + </entry> + </row> + <row> + <entry> + newAgent + </entry> + <entry> + agent + </entry> + <entry> + a new agent appears on the QMF bus + </entry> + </row> + <row> + <entry> + delAgent + </entry> + <entry> + agent + </entry> + <entry> + an agent disconnects from the QMF bus + </entry> + </row> + <row> + <entry> + objectProps + </entry> + <entry> + broker, object + </entry> + <entry> + the properties of an object are published + </entry> + </row> + <row> + <entry> + objectStats + </entry> + <entry> + broker, object + </entry> + <entry> + the statistics of an object are published + </entry> + </row> + <row> + <entry> + event + </entry> + <entry> + broker, event + </entry> + <entry> + an event is published + </entry> + </row> + <row> + <entry> + heartbeat + </entry> + <entry> + agent, timestamp + </entry> + <entry> + a heartbeat is published by an agent + </entry> + </row> + <row> + <entry> + brokerInfo + </entry> + <entry> + broker + </entry> + <entry> + information about a connected broker is available to be + queried + </entry> + </row> + <row> + <entry> + methodResponse + </entry> + <entry> + broker, seq, response + </entry> + <entry> + the result of an asynchronous method call is received + </entry> + </row> + </tbody> + </tgroup></table><para> + Supplied with the API is a class called <emphasis>DebugConsole</emphasis>. + This is a test <emphasis>Console</emphasis> instance that overrides all of + the methods such that arriving asynchronous data is printed to + the screen. This can be used to see all of the arriving + asynchronous data. + </para> + <!--h2--></section> + + <section role="h2" id="QMFPythonConsoleTutorial-ReceivingEvents"><title> + Receiving + Events + </title> + + <para> + We'll start the example from the beginning to illustrate the + reception and handling of events. In this example, we will create + a <emphasis>Console</emphasis> class that handles broker-connect, + broker-disconnect, and event messages. We will also allow the + session manager to manage the broker connection for us. + </para><para> + Begin by importing the necessary classes: + </para> + <programlisting> +>>> from qmf.console import Session, Console +</programlisting> + <para> + Now, create a subclass of <emphasis>Console</emphasis> that handles the three + message types: + </para> + <programlisting> +>>> class EventConsole(Console): +... def brokerConnected(self, broker): +... print "brokerConnected:", broker +... def brokerDisconnected(self, broker): +... print "brokerDisconnected:", broker +... def event(self, broker, event): +... print "event:", event +... +>>> +</programlisting> + <para> + Make an instance of the new class: + </para> + <programlisting> +>>> myConsole = EventConsole() +</programlisting> + <para> + Create a <emphasis>Session</emphasis> class using the console instance. In + addition, we shall request that the session manager do the + connection management for us. Notice also that we are requesting + that the session manager not receive objects or heartbeats. Since + this example is concerned only with events, we can optimize the + use of the messaging bus by telling the session manager not to + subscribe for object updates or heartbeats. + </para> + <programlisting> +>>> sess = Session(myConsole, manageConnections=True, rcvObjects=False, rcvHeartbeats=False) +>>> broker = sess.addBroker() +>>> +</programlisting> + <para> + Once the broker is added, we will begin to receive asynchronous + events (assuming there is a functioning broker available to + connect to). + </para> + <programlisting> +brokerConnected: Broker connected at: localhost:5672 +event: Thu Jan 29 19:53:19 2009 INFO org.apache.qpid.broker:bind broker=localhost:5672 ... +</programlisting> +<!--h2--></section> + + <section role="h2" id="QMFPythonConsoleTutorial-ReceivingObjects"><title> + Receiving + Objects + </title> + + <para> + To illustrate asynchronous handling of objects, a small console + program is supplied. The entire program is shown below for + convenience. We will then go through it part-by-part to explain + its design. + </para><para> + This console program receives object updates and displays a set + of statistics as they change. It focuses on broker queue objects. + </para> + <programlisting> +# Import needed classes +from qmf.console import Session, Console +from time import sleep + +# Declare a dictionary to map object-ids to queue names +queueMap = {} + +# Customize the Console class to receive object updates. +class MyConsole(Console): + + # Handle property updates + def objectProps(self, broker, record): + + # Verify that we have received a queue object. Exit otherwise. + classKey = record.getClassKey() + if classKey.getClassName() != "queue": + return + + # If this object has not been seen before, create a new mapping from objectID to name + oid = record.getObjectId() + if oid not in queueMap: + queueMap[oid] = record.name + + # Handle statistic updates + def objectStats(self, broker, record): + + # Ignore updates for objects that are not in the map + oid = record.getObjectId() + if oid not in queueMap: + return + + # Print the queue name and some statistics + print "%s: enqueues=%d dequeues=%d" % (queueMap[oid], record.msgTotalEnqueues, record.msgTotalDequeues) + + # if the delete-time is non-zero, this object has been deleted. Remove it from the map. + if record.getTimestamps()[2] > 0: + queueMap.pop(oid) + +# Create an instance of the QMF session manager. Set userBindings to True to allow +# this program to choose which objects classes it is interested in. +sess = Session(MyConsole(), manageConnections=True, rcvEvents=False, userBindings=True) + +# Register to receive updates for broker:queue objects. +sess.bindClass("org.apache.qpid.broker", "queue") +broker = sess.addBroker() + +# Suspend processing while the asynchronous operations proceed. +try: + while True: + sleep(1) +except: + pass + +# Disconnect the broker before exiting. +sess.delBroker(broker) +</programlisting> + <para> + Before going through the code in detail, it is important to + understand the differences between synchronous object access and + asynchronous object access. When objects are obtained + synchronously (using the <emphasis>getObjects</emphasis> function), the + resulting proxy contains all of the object's attributes, both + properties and statistics. When object data is published + asynchronously, the properties and statistics are sent separately + and only when the session first connects or when the content + changes. + </para><para> + The script wishes to print the queue name with the updated + statistics, but the queue name is only present with the + properties. For this reason, the program needs to keep some state + to correlate property updates with their corresponding statistic + updates. This can be done using the <emphasis>ObjectId</emphasis> that + uniquely identifies the object. + </para> + <programlisting> + # If this object has not been seen before, create a new mapping from objectID to name + oid = record.getObjectId() + if oid not in queueMap: + queueMap[oid] = record.name +</programlisting> + <para> + The above code fragment gets the object ID from the proxy and + checks to see if it is in the map (i.e. has been seen before). If + it is not in the map, a new map entry is inserted mapping the + object ID to the queue's name. + </para> + <programlisting> + # if the delete-time is non-zero, this object has been deleted. Remove it from the map. + if record.getTimestamps()[2] > 0: + queueMap.pop(oid) +</programlisting> + <para> + This code fragment detects the deletion of a managed object. + After reporting the statistics, it checks the timestamps of the + proxy. <emphasis>getTimestamps</emphasis> returns a list of timestamps in the + order: + </para><itemizedlist> + <listitem><para> + <emphasis>Current</emphasis> - The timestamp of the sending of this update. + </para></listitem> + <listitem><para> + <emphasis>Create</emphasis> - The time of the object's creation + </para></listitem> + <listitem><para> + <emphasis>Delete</emphasis> - The time of the object's deletion (or zero if + not deleted) + </para></listitem> + </itemizedlist><para> + This code structure is useful for getting information about + very-short-lived objects. It is possible that an object will be + created, used, and deleted within an update interval. In this + case, the property update will arrive first, followed by the + statistic update. Both will indicate that the object has been + deleted but a full accounting of the object's existence and final + state is reported. + </para> + <programlisting> +# Create an instance of the QMF session manager. Set userBindings to True to allow +# this program to choose which objects classes it is interested in. +sess = Session(MyConsole(), manageConnections=True, rcvEvents=False, userBindings=True) + +# Register to receive updates for broker:queue objects. +sess.bindClass("org.apache.qpid.broker", "queue") +</programlisting> + <para> + The above code is illustrative of the way a console application + can tune its use of the QMF bus. Note that <emphasis>rcvEvents</emphasis> is + set to False. This prevents the reception of events. Note also + the use of <emphasis>userBindings=True</emphasis> and the call to + <emphasis>sess.bindClass</emphasis>. If <emphasis>userBindings</emphasis> is set to False + (its default), the session will receive object updates for all + classes of object. In the case above, the application is only + interested in broker:queue objects and reduces its bus bandwidth + usage by requesting updates to only that class. + <emphasis>bindClass</emphasis> may be called as many times as desired to add + classes to the list of subscribed classes. + </para> +<!--h2--></section> + + <section role="h2" id="QMFPythonConsoleTutorial-AsynchronousMethodCallsandMethodTimeouts"><title> + Asynchronous Method Calls and Method Timeouts + </title> + + <para> + Method calls can also be invoked asynchronously. This is useful + if a large number of calls needs to be made in a short time + because the console application will not need to wait for the + complete round-trip delay for each call. + </para><para> + Method calls are synchronous by default. They can be made + asynchronous by adding the keyword-argument _<emphasis>async=True</emphasis> + to the method call. + </para><para> + In a synchronous method call, the return value is the method + result. When a method is called asynchronously, the return value + is a sequence number that can be used to correlate the eventual + result to the request. This sequence number is passed as an + argument to the <emphasis>methodResponse</emphasis> function in the + <emphasis>Console</emphasis> interface. + </para><para> + It is important to realize that the <emphasis>methodResponse</emphasis> + function may be invoked before the asynchronous call returns. + Make sure your code is written to handle this possibility. + </para> + <!--h2--></section> + <!--h1--></section> + + <section role="h1" id="QMFPythonConsoleTutorial-DiscoveringwhatKindsofObjectsareAvailable"><title> + Discovering what Kinds of Objects are Available + </title> + <para/> + <!--h1--></section> + + +</section> |