On 3/15/07, Glynn, Eoghan <[EMAIL PROTECTED]> wrote:
Dan, There are a bunch of orthogonal issues becoming conflated in this discussion. So I'm going to take a step back and try disentangling the following: 1. transport-specific versus generic mechanism to set the decoupled response endpoint (DRE) 2. policy-driven (either specified via XML config or programmatically) versus some other API to set the DRE 3. cardinality of the DRE, i.e. one-per-something (Conduit or Client), or unlimited 4. association of the DRE with the Conduit or the Client instance 5. lifecycle mgmt of the DRE, or how to trigger a shutdown 6. explicit application creation and shutdown of DREs Dealing with each issue in turn, here's my position: 1. If its claimed a proposed new mechanism for setting the DRE is superior to the existing mechanism by virtue of its genericity, then I don't think its unreasonable to expect it be really generic, as opposed to sortta generic except for 'edge-case' transports. If some transport specifics are required, lets at least try to dove-tail these with the general mechanism as neatly as possible.
I would propose just letting users set an EPR and then resurrecting DestinationFactory.getDestination(EPR). In this case its up to the transport to understand the EPR. Its a generic mechanism. JMS may not work right away, but we can make it work eventually. If you have any other ideas feel free to share them. 2. Since we already control transports via policies specified either in
XML config or programmatically, then for consistency it makes sense IMO to stick with this model. We could genericize the policy by moving the DecoupledEndpoint attribute to a new ConduitPolicy and having the existing HTTPClientPolicy pick it up from there by type extension. Other transports would also extend ConduitPolicy with their own client policy type if necessary and could I guess add any additional info they need (thus neatly solving the JMS issue). The generic ConduitPolicy could be exposed via the AbstractConduit. Then programmatic approach (as used for example in the RM SequenceTest) could then also become generic (i.e. call AbstractConduit.getConduitPolicy() as opposed to HTTPConduit.getClient() to get a hold of the policy object).
-1: as I stated in my other email, there isn't any reason to put the DRE inside the conduit. It is much more straightforward to put the Destination on the Client and and have the Client shutdown both the Conduit & DRE. Its completely unncessary to introduce yet more complexity into our transport APIs for this. 3. My main issue was to avoid a proliferation of automatically launched
DREs, as the responsibility for the lifecycle mgmt of these DREs should be the responsibility of CXF. Fair enough, the DRE shutdown isn't done properly currently, but it would be a tractable problem to do so, by virtue of the cardinality being limited to one-per-Conduit. My whole point was that we shouldn't move to a scenario where for example the application setting a replyTo on an AddressingProperties instance set in request context would cause CXF to automatically launch a new listener. The problem here of course is that allowing a per-request setting would facilitate the application causing many listeners to be created by CXF, without a good way for the CXF runtime to know when these should be shutdown. I take it from your comments in more recent mails on this thread that this is not the sort of mechanism you're looking for, correct?
I just want to do : Client c = ... c.setDecoupledEndpoint(myEPR); c.invoke(...); c.close(); (I'm not 100% sure that it should setDecoupledEndpoint. Other options are setAsynchronousEndpoint or setReplyTo) Also, I would like to be able to do: Client c = ... c.setDestination(myDestination); c.invoke(...); c.close(); I don't think it makes sense to have two ways to specify a decoupled endpoint (i.e. one hidden inside the Conduit and one in which the destination is looked up). 4. I would favour continuing to associate the DRE with the Conduit as
opposed to the Client, because a) the DRE is transport-level concern IMO
I disagree. Transports (i.e. Conduits) are a tool to do decoupled interactions. Putting the DRE inside the conduit results in a) API complexity. Moving the destination outside of the conduit makes it more straightforward to write Conduits and also easier to specify DREs for interactions. You also need to introduce even more complexity by adding the ConduitPolicy class. b) Inconsistency - If people have to set up a Destination manually when they use per-request addressing settings, I don't see why we should have a different API for setting up decoupled destinations when you're setting up a DRE for the life time of a Client. and b) there may not even be a Client instance involved in mediating the
invocation (e.g. when using the JAX-WS Dispatch mechanism).
The JAX-WS Dispatch should be using the Client. I have an open JIRA for this I thought... (I fixed the Provider side of things but ran out of time on the Dispatch end) 5. The lifecycle management is much easier to deal with if the
cardinality is limited as per #3. As I said before I'm happy with your suggested explicit Client.close() API (which would presumably call down to Conduit.close()).
+1 to limiting it to per Client. If people are doing something more complex they get to manage it themselves. 6. The application should IMO be free to set a replyTo for a DRE *not*
created by CXF, for example if that DRE is controlled by the some third party, or if the application explicitly calls DestinationFactory.getDestination() itself and is prepared to handle the shutdown when its done. Not sure if your comment "I'm -1 to having two mechanisms to do the same exact same thing" indicates disagreement on this point(?)
I agree we should add a mechanism to tell CXF not to create a decoupled endpoint. The best thing would be if CXF could see that the user specified their own destination: Client client = ...; client.setDestination(myDestination); In this case they wouldn't have to set an EPR, it could just figure out the EPR from Destination.getAddress(); Also, If I specify an EPR and a Destination already exists for that EPR, CXF should be able to just use that. DestinationFactorys aren't holding on to the Destinations they create which I think is bad. If they do hold on to them, when I call getDestination() it should just reuse the one that is already there. The destination can be released once shutdown() is called, so there shouldn't be any lifecycle concerns. - Dan -- Dan Diephouse Envoi Solutions http://envoisolutions.com | http://netzooid.com/blog
