[openstack-dev] [OSLO][RPC] AMQP / ZeroMQ control_exchange vs port numbers
Mark McLoughlin
markmc at redhat.com
Mon Apr 29 15:45:11 UTC 2013
On Mon, 2013-04-29 at 10:55 -0400, Doug Hellmann wrote:
>
>
>
> On Mon, Apr 29, 2013 at 10:23 AM, Mark McLoughlin <markmc at redhat.com> wrote:
> On Mon, 2013-04-29 at 09:39 -0400, Doug Hellmann wrote:
> >
> >
> >
> > On Mon, Apr 29, 2013 at 7:00 AM, Mark McLoughlin <markmc at redhat.com> wrote:
> > On Fri, 2013-04-26 at 15:18 -0400, Doug Hellmann wrote:
> >
> > > We've gone around a few times with ideas for having better driver-parity in
> > > the rpc library, so maybe the best thing to do is start by making sure we
> > > have all of the requirements lined up. Here's a list of some that I came up
> > > with based on existing features and my understanding of the shortcomings
> > > (numbered for reference, but in no particular order):
> >
> >
> > Thanks for doing this. We definitely need to be stepping back and
> > thinking about this at a high level. I've attempted to step a little
> > further back in my writeup:
> >
> > https://wiki.openstack.org/wiki/Oslo/Messaging
> >
> > > 1. Application code using RPC connections must not be required to know to
> > > pass different arguments to establish the connection (i.e., the app
> > > shouldn't have to care if it is using Rabbit or ZMQ).
> >
> >
> > Yes.
> >
> > > 2. An application must be able to direct a message to a specific peer
> > > (i.e., call() with a host specified).
> >
> >
> > s/direct a message to/invoke a method on/
> >
> >
> > RPC and notification aren't the only usage patterns for messaging. If
> > we're going to design a general purpose library, we should not limit
> > ourselves to RPC semantics. RPC can be built on top of messaging, but
> > it has been painful to try to make it work the other way around.
>
>
> I don't think the goal is to design a general purpose library, it's to
> clean up the APIs we already have to support our current usage patterns.
> The library can grow new APIs to support new usage patterns over time.
>
> I really don't want to design generic APIs in a vacuum when we have the
> much more pressing concern of our current usage patterns. I also don't
> want to unnecessarily restrict what messaging systems could be used to
> support our current patterns.
>
>
> You've already, mostly, separated the transport stuff from the RPC
> semantics. I think that's all I was asking for, but I want the way we
> describe it to not say "invoke a method on" but just stick with
> message delivery. The dispatcher for method invocation is one
> server-side detail.
I think about it more in terms of the payload - I don't want users of
the API ever to see this as "sending a message with 'method' and 'args'
parameters'" ... it should be "invoke a method with the given name and
args".
If we want to support messaging with alternative or free-form payloads,
then we can do that later - right now, we don't have a use case for it.
> > But, yes.
> >
> > > 3. An application must be able to direct a message to a pool of peers
> > > (i.e., cast()).
> >
> >
> > ... and for it to be delivered to one of those peers, yes.
> >
> > > 4. An application must be able to direct a message to a specific peer (or
> > > unknown? or both?) using a different rpc endpoint than the originating
> > > app's default (i.e., calling into cells).
> >
> >
> > I've tried to separate the notion of a transport from the target. The
> > properties of the target is what's known to the application code, the
> > properties of the transport are target specific and come from
> > configuration.
> >
> > So, I'd say "an application must be able to invoke a method on a
> > specific target using a supplied transport configuration".
> >
> >
> > Something has to know how to map the target to the configuration. What
> > does that, and how much does that code know about the transport?
>
>
> Ok, on the client side:
>
> https://wiki.openstack.org/wiki/Oslo/Messaging#Client_Side_API
>
> for the simple case, you'd have something like:
>
> rpc_driver = rpc.get_transport_driver()
>
> base_rpcapi = BaseAPIClient(rpc_driver)
>
> base_rpcapi.ping(context, 'foo')
>
> for the more complex case, you'd have:
>
> class MeteringAPIClient(rpc.RPCClient):
>
> target = rpc.Target(exchange='ceilometer',
> topic='metering',
> version='1.0')
>
> def __init__(self, driver):
> # FIXME: need some way to override with exchange from URL
>
>
> Ceilometer knows which exchanges to listen on based on its plugins and
> configuration (we know to look for the glance notification config
> option when the glance-related plugins are activated, for example).
Right, and this is relevant to the notifications consumption API.
> Cells will know because they will have some configuration setting(s)
> per cell they want to talk to in the database.
Yes, and this is why I want to support it in the transport URL.
> Are those the only cases we have now? Are they the only cases we
> anticipate?
Well, we also have the control_exchange config varibale. So we need to
default to control_exchange, but allow the transport driver URL to
override it?
The MeteringAPIClient example I had in mind above was the code for a
Nova notifications plugin - the code runs in Nova, so control_exchange
will be 'nova' but we know the default should be 'ceilometer' even if it
gets overridden by the transport URL.
> ---
>
> rpc_driver = rpc.get_transport_driver(url='kombu://broker//ceilometer')
>
> metering_rpcapi = MeteringAPIClient(rpc_driver)
> metering_rpc_api.record_metering_data(...)
>
> The annoying bit here is the application code should know what the
> default exchange is, but there is a use case for it to be overridden by
> configuration.
>
>
> If the application gets the URL to pass to get_transport_driver() from
> a config file or the database, does it even need to know there is such
> a thing as an "exchange" any more?
It needs to know what the default is - i.e. Nova needs to set it to
'nova' process-wide and Ceilometer's notification plugin needs it to be
'ceilometer'
Cheers,
Mark.
More information about the OpenStack-dev
mailing list