Gary, Bob, I figured since both of you had expressed some interest in the rpc API for use in Quantum, I would give a quick intro to the API to help get you started (and CC the openstack list for anyone else that may benefit).
The best way to start is to look at how the code is used in nova. The public API can be found in nova/rpc/__init__.py. Note that I'm in the middle of adding more to the public rpc API in this feature branch to add API versions: https://github.com/russellb/nova/tree/bp/versioned-rpc-apis == SERVER SIDE You can find an example of the server side in nova/service.py: https://github.com/openstack/nova/blob/master/nova/service.py#L196 This code does a few important things: 1) Create an rpc connection. 2) Create 3 consumers on the connection. 3) Spawn a thread to handle incoming messages. You'll see that in the nova code, three consumers are created. This is to set up 3 different messaging patterns. Let's assume that this code is running for service 'nova-foo'. In that case, self.topic would be 'foo'. pattern 1: # Share this same connection for these Consumers self.conn.create_consumer(self.topic, self, fanout=False) For pattern 1, all instances of the 'nova-foo' service are creating a consumer with topic 'foo'. When a message is sent to topic 'foo' using the client side of the rpc API, it goes to exactly one instance of the nova-foo service. If AMQP is the messaging backend for rpc, messages to the 'foo' topic are delivered round-robin. pattern 2: node_topic = '%s.%s' % (self.topic, self.host) self.conn.create_consumer(node_topic, self, fanout=False) For pattern 2, each nova-foo service is creating its own topic using the hostname - foo.<host>. This topic is used to target messages to a specific host. pattern 3: self.conn.create_consumer(self.topic, self, fanout=True) Pattern 3 is a broadcast. The topic is set to 'foo' here, but fanout is True. When a client sends a fanout message to 'foo', *all* instances of nova-foo will get the message. The other important thing here is the meaning of the second argument to create_consumer(). This is the object that is the target of all rpc messages. When an rpc message comes in saying to run a method, the code looks at this object for that method to run. == CLIENT SIDE The most important client side functions are: cast() call() fanout_cast() multicall() You'll also see cast_to_server() and fanout_cast_to_server(), but you should probably ignore those for now, as I believe they will be going away at some point. cast() is for sending a one-way message. call() is for sending a message and waiting the return value from the remote method. fanout_cast() is a one-way broadcast message. multicall() isn't actually used anywhere in nova, but it may be useful at some point. multicall() is a variant of call() that allows the remote method to return multiple values and allows the client to process them as they occur. You can think of it as calling a remote generator and rpc.multicall() returns an iterator to allow you to process those results as they come in. Each of these client-side methods take a topic argument which is used for targeting the message. The message argument is a Python dict in the form: {'method': remote_method_to_run_as_str, 'args': dict_of_kwargs}. Note that you don't have to do any explicit creation of a connection for the client side of this API. It uses a connection pool behind the scenes. You can search around through nova to find many uses of these functions. Let me know if you have any questions! -- Russell Bryant _______________________________________________ Mailing list: https://launchpad.net/~openstack Post to : openstack@lists.launchpad.net Unsubscribe : https://launchpad.net/~openstack More help : https://help.launchpad.net/ListHelp