On 26/04/13 17:18, Ken Giusti wrote:
Hey Bill,


I first started to implement the additional objectUpdate callback as originally 
proposed.  Very easy to do.  But that additional api required other tools to be 
updated - and additional documentation changes, etc.
Hmm I remain a little baffled here. So as I understood it prior to any fixing going on here there existed a bug that actually prevented QMF2 updates actually hitting callbacks on the asynchronous python API, that's good IMHO because most clients of that API almost certainly were expecting a single callback call for a given object.

I'm kind of unclear about "other tools to be updated" 'cause I'd have assumed given the previous QMF2 bug that no existing tools were actually receiving v2 updates so wouldn't need "fixed". Sure they will need modified to handle V2 if they want to consume both, but I'd argue that it might be better to modify tools that need to handle both than to risk breaking changes which will blat an indeterminate number of third party tools. It's not ideal for sure, but a non-breaking API extension requiring an addition to clients to use it feels better and TBH it's actually clearer IMHO because there's some conscious choice being made.


After implementing this, I discovered a problem with the fix: tools that need 
to monitor both QMFv1 and QMFv2 agents starting reporting incorrect results 
(qpid-tool, to be specific).  These tools need to support both the old 
callbacks (for QMFv1 updates) and the new one (for QMFv2 updates), in order to 
see both QMFv1 and QMFv2 agents.
To be honest as I suggest above IMHO I actually think it's a good thing for tools that wish to support both to be explicit. I think from the various sections of this thread it's pretty clear that trying to crowbar everything together is a *bad idea*. Sure QMF1 and QMF2 are essentially representing equivalent information but there are sufficient differences and subtleties to flash a great big red light. The reason it's good to have a separate objectUpdate is because the QMF2 API *is* different at that point because the protocol is sending what amounts to incompatible data.

At that point there are two choices 1) an additional non-breaking API callback or 2) a shim in the client side that makes things behave identically.

The latter may be a bad choice if both v1 and v2 updates arrive because it'd need to apply a filter for the case of v1 plus v2 but it'd probably be a good choice if it could select either v1 or v2 because then existing clients wouldn't need to be modified at all.




And that's when I realized that this fix was just a hack to work around the 
actual problem.  The real issue at hand is that a QMF agent must not transmit 
both QMFv1 and QMFv2 updates for the same object.

That's really what's broken here, and the C++ broker is doing precisely that.
Whoa there :-) I think that the problem is that this is *exactly* what it should be doing :-)

OK what I mean is how does it know? Bear in mind that the updates causing the fun here are *unsolicited* data pushes! These updates are being pushed to a topic, so unless any client is subscribing to qmf.default.topic/data.ind.# or whatever it isn't going to be getting v2 updates, similarly if it's not subscribing to the equivalent on qpid.management/ it's not going to be getting v1 updates. OTOH if it's subscribing to both that's exactly what it's getting.

The key thing is there's a fairly large level of decoupling going on here, so I don't believe that there's an especially easy way for the broker ManagementAgent to work out who's asking for what and thus avoid transmitting both v1 and v2.


Funnily enough in the v2 protocol and API there's actually no concept of an *unsolicited* data push, so I'd argue that what the broker is currently doing for the v2 updates is an "undocumented feature" :-), what V2 actually talks about is the concept of "query subscriptions". With query subscriptions the asynchronous pushes are actually *solicited* by the client actually requesting some specified subset of the data, so the Management Agent does actually have a mechanism to track what data any given subscribers are actually interested in.

That's clearly a moot point, but it would help with this pickle.


I was musing over this problem and I believe that there is an option, albeit a non-trivial one :-(

So the *real* issue is that it's difficult to manage the carnage caused when both v1 and v2 updates happen. You've previously suggested disabling v1 by default, I've sort of got sympathy with that :-) However there are two (I suspect significant) use cases that will be impacted by that choice: 1) Any asynchronous console that relies on the existing v1 callbacks will stop working - I suspect that in practice that'll mean every single darned one of them except (at a push) qpid-tool. There may be a lot of third party tools using this API so it may be an issue. At the very least there needs to be some real good communication to the user list. 2) If you disable v1 then any third party Agents will break too. Again perhaps they need to change to v2 and this is a catalyst, but it just may cause non-trivial business impact on users.

Ultimately I think that it's very worth pushing out a survey on the user list to gauge the potential impact.

The non-trivial mitigation that I was musing over was whether there was a possibility of constructing a v1->v2 bridge Agent? What I mean is that it might be possible to get the broker ManagementAgent to only send v2 updates if there's a mechanism for the broker to intercept v1 updates from third party Agents and map those into v2 too, thus making every data push consistently V2? I *think* this could work because I believe that v1 requires broker involvement in order to work (I think that was one of the reasons for moving to v2).

If it were possible to get to a clear point of only sending v2 updates then it should be possible to have the asynchronous Console API shimmed in such a way that it behaves *exactly* the same way with v2 updates as it did with v1 updates so it's possible to mitigate the impact on third party console applications (yay!).

It has to be said It's be much better if users didn't have to rewrite applications because of objectUpdate versus propUpdate/statUpdate but clearly a shim would be required to make v2 updates behave correctly and transparently for propUpdate/statUpdate callbacks.

The result of the survey question "how many people have custom v1 Agents" would help determine whether it's worth investing in a v1->v2 bridge Agent.

A bridge ought to be possible, that's actually exactly what I wrote for the Java Broker in the Qmf2ManagementAgent to get that to talk QMF2 (albeit I was mapping from its internal model and not QMF1, but the principal is the same - just don't ask me to do it in C++ though :-))



Why is that a problem?  Because a console receiving these two updates cannot 
tell that they are for the same object.  To the console application, it appears 
as two separate objects.
As I mention above I don't believe that it's any easier for the broker to do a "diff" given the unsolicited nature of these updates :-)
I'm proposing that we should solve this problem by disabling QMFv1 updates 
coming from the C++ broker.  This should be the default for the next release 
(0.26).  It should still be possible to turn them on manually if desired, but 
the C++ broker should only transmit QMFv2 type updates going forward.
As I say above I've got a fair amount of sympathy with this, and parochially if it means that by doing this you can make statUpdate and propUpdate for v2 behave *exactly* the same as for v1 so clients don't need to be rewritten for v2 then it'd be better for me 'cause I only ever use v2 aside from this.

However as I said above the only reason that this Console API ever supported both was to cater for the case where a user needed to handle both v1 and v2 updates and that use case is actually third party v1 Agents.

I think it's important to at least check for how much impact this is going to cause users.



We can minimize the impact to console applications by having the objectProps 
and objectStats callbacks be invoked when a QMFv2 object arrives instead of 
introducing a new callback. [Bill - I'll fix the console to not call 
objectProps when only stats are present].  I think this should eliminate the 
need to re-code console applications.
So I don't think it's about "minimising the impact" I think that the API needs to behave *exactly* the same for this to be any use. Basically any asynchronous client hit by only v2 updates should behave identically to how they behaved prior to this update or it's still introducing a regression into an indeterminate number of applications. I've no idea how hard it'd be to achieve this nirvana though.


This will cause problems for folks that use an old python console against the 
next release of the broker.  These folks will have to upgrade the console as 
well.

Does anyone have a better alternative?
Well I'm not necessarily saying that my suggestions above are *better* :-) It's difficult for sure. I guess that my biggest concern is introducing breaking changes against an unknown number of third party Consoles and Agents.

One other thing makes me nervous. I guess that there's the scenario where users are working with a mixed economy of brokers at different versions or who (like Bill) may be unable to alter the broker config to only push out a particular version.

All brokers from at least 0.8 can push out v2 so it *might* be safe to have the console only subscribe to v2 updates (providing a switch to specify v1). If you can make propUpdate and statUpdate behave consistently then that only leaves the case where there are v1 Agents to support, which is where the bridge Agent may come in.

How much do you regret starting on this fix now Ken? :-D


It's worth pointing out that this is I suspect only the tip of the iceberg for the sort of problems that might start to be encountered when migration to AMQP 1.0 Management starts to gain traction. My strong hunch is that bridge Agents/ManagementNodes are going to become pretty important friends when it comes to trying to manage any transition. It's something that's going to bite sooner or later and the C++, Java & Python communities are going to have to be pretty joined up. I quite like QMF, but clearly some mistakes were made along the way given the lack of support in the Java community and frankly the fragmentation of APIs and lack of take up on the "official" QMF2 API. We *really* need to try harder next time round and act as an exemplar in the AMQP community.

Frase













---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to