[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++
At the moment we’ve been casting
the return from service to a CustomerService* (in this case), which is the base
interface that the user used to define their interface. I would normally
expect that to be a proxy instance as well, however in the current model I didn’t
see any reason why an SCA runtime couldn’t return the customers concrete implementation
instead (for instance if both the caller and callee are running in the same
process). With the introduction of the Async APIs, it doesn’t seem
like that is the case any longer, and we should always be returning a proxy
instance, even in the case where caller and callee are in the same process. I think I see three routes we can go: 1) Assume (require) that it is always a
proxy In this case, it doesn’t seem like we
should be using the original interface class directly, and instead should be
returning (and casting to) a proxy class interface. The proxy class
interface would provide the same API as the original C++ interface (possibly by
deriving from it), but would also include additional APIs specific to the proxy
(such as the *Async functions), and could provide basic functionality that is
common to all proxies (allowing the user to customize the binding or endpoint
or something else? I’m not sure what would make sense here).
In this case, I think it would make sense to update all of our examples to
indicate that a proxy is being returned from the getService() calls, i.e
instead of getting a CustomerService*, they’d get a
CustomerServiceProxy*, and includes and other factors would need to change).
We should also provide additional details on the code generation process for
that proxy interface. Offhand that seems to include the addition of the
Async methods beyond the normal synchronous methods from the original
interface. I’m not sure whether we should just always generate
these functions, or only generate them if the asyncInvocation intent is
specified. It seems like if we’re going to rely on the
asyncInvocation, then an implementation would need to include the SCDL files in
the code generation process (since they are the definitive source for these
properties, right?). 2) Assume that it can be the user’s
implementation class or a proxy In this case, a customer would still need
to initially get the service back as their interface type (CustomerService*),
and then would/should dynamic_cast<> it to a CustomerServiceProxy* if
they want to access some of the extension methods, like *Async. If it’s
a user implementation class, the dynamic_cast will fail (return 0) and they’ll
know that those APIs aren’t available. If it succeeds, they’ll
be able to use the asynchronous APIs. I think in this case we would still
need to discuss the code generation process for the proxy interface (same as
above), and we would need to provide additional details in the async chapter to
discuss casting to the proxy when they want access to those functions. 3) Require the user’s interface to
declare the Async methods. When a user is defining their interface,
if they want to support asynchronous operations, they’ll need to provide
the appropriate methods on their interface. This would require no changes
to the way that we currently handle services, however we’ll then need to
deal with the disconnect where a composite indicates that asyncInvocation should
be used (or at least is available) on a service where the interface does not
provide the async methods. We’ll also need to look at our
WSDL->C++ mapping and determine when our generated interface should include
the Async functions. Off hand I would lean towards (1) or (2),
as I don’t like the idea of pushing the asynchronous APIs on to the
service writer. It seems like those are the kinds of things that should
be managed by the runtime. In that case, I don’t think we should dance
around the proxy question, and the spec should be clear that a proxy MUST or at
least MAY be returned from the getService() call, and what the API of the proxy
will look like. Otherwise we’ll head down the path of
implementation-specific definitions for the proxies that may make it difficult
to write portable code. Thanks.
From: Bryan Aupperle
[mailto:aupperle@us.ibm.com]
The
getService() member function takes as its input
argument the name of the reference and returns a pointer to an object providing
access to the service. The returned object will implement the abstract base
class definition that is used to describe the reference. The
following shows a sample of how the ComponentContext is used in
a C++ component implementation. The getService() member
function is called on the ComponentContext passing the
reference name as input. The return of the getService() member
function is cast to the abstract base class defined for the reference. #include
"ComponentContext.h"
|
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]