OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

sca-c-cpp message

[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++


I’ve updated the proposal to use the explicit dynamicCast variant.  This includes:

 

-          Updating all of the examples to use the dynamicCast syntax.

-          Updating the API portion of the spec to include the four new global cast functions.

 

Thanks.


David.

 


From: David Haney [mailto:haney@roguewave.com]
Sent: Monday, February 23, 2009 8:24 AM
To: Bryan Aupperle; sca-c-cpp@lists.oasis-open.org
Subject: RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++

 

The following is sample code describing the two mechanisms that we discussed in the last meeting for casting between RefCountingPointer types.

 

mechanism performs the conversion implicitly as a part of construction, and is the method that we've been using in the sample code so far.

 

  Pointer<Y> y1 = x;

 

The second mechanism performs the conversion explicitly:

 

  Pointer<Y> y2 = dynamicCast<Y>(x);

 

The former is more concise, however it also provides the user with less control (they can't control how the cast will occur).  It does however provide more freedom to the implementor to determine how casting could occur (allowing them to make it more efficient in some cases, and unfortunately less portable in others).

 

The latter is more explicit (it's clear that we're performing a dynamic cast), and more flexible.  We could just as easily provide support for static or reinterpret casts, and support those as well.

 

--- BEGIN CODE

#include <stdio.h>

 

template <typename T>

class Pointer {

  public:

    Pointer(T* ptr) : ptr_(ptr) {}

   

    template <typename U>

    Pointer(Pointer<U> ptr) : ptr_(dynamic_cast<T*>(ptr.ptr_)) {}

   

    T* ptr_;

};

 

template <typename T, typename U>

Pointer<T> dynamicCast(Pointer<U> other) {

  return Pointer<T>(dynamic_cast<T*>(other.ptr_));

}

 

class X {

  public:

  virtual ~X() {}

};

 

class Y : public X {

  public:

  virtual ~Y() {}

};

 

class Z {

  public:

  virtual ~Z() {}

};

 

int main(void) {

  Pointer<X> x(new Y());

 

  Pointer<Y> y1 = x;

  fprintf(stderr, "%s\n", y1.ptr_ != 0 ? "true" : "false");

 

  Pointer<Y> y2 = dynamicCast<Y>(x);

  fprintf(stderr, "%s\n", y2.ptr_ != 0 ? "true" : "false");

 

  Pointer<Z> z1 = x;

  fprintf(stderr, "%s\n", z1.ptr_ == 0 ? "true" : "false");

 

  Pointer<Z> z2 = dynamicCast<Z>(x);

  fprintf(stderr, "%s\n", z2.ptr_ == 0 ? "true" : "false");

 

  return 0;

}

-- END CODE

 

Thanks.

 

David.

 


From: Bryan Aupperle [mailto:aupperle@us.ibm.com]
Sent: Friday, February 20, 2009 11:42 AM
To: sca-c-cpp@lists.oasis-open.org
Subject: RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++

 


Here is a pass at a merge of my proxy proposal and David's async invocation proposal.

This leaves proxy generation for local interfaces direct from C++ for now.

Bryan Aupperle, Ph.D.
STSM, WebSphere Enterprise Platform Software Solution Architect

Research Triangle Park,  NC
+1 919-254-7508 (T/L 444-7508)
Internet Address: aupperle@us.ibm.com

"David Haney" <haney@roguewave.com>

02/17/2009 04:21 PM

To

"Pete Robbins" <ROBBINS@uk.ibm.com>, <sca-c-cpp@lists.oasis-open.org>

cc

 

Subject

RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++

 

 

 




Attached is an updated version of the proposal for Issue 54.  The response object has been updated so that it can be used for callbacks, polling, or synchronous access.  The function pointer has been replaced with a function object, and various interfaces have been updated or moved around.  All of the examples assume that a ServiceProxy is always returned, so this update may need to be put on hold until a more complete review of the spec has been done to switch to using ServiceProxies instead of void*.
 
Thanks.
 
David.
 

 



From: Pete Robbins [mailto:ROBBINS@uk.ibm.com]
Sent:
Monday, February 16, 2009 11:01 AM
To:
sca-c-cpp@lists.oasis-open.org
Subject:
RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++

 

I think we have to go with (1), always return a proxy. As is pointed out the runtime should always be able to know when control is passed between components.


Way back in the beginnings of time we did consider mandating that all services would inherit from a base class... and rejected it. I don't think that is what you are suggesting here. I think you are saying that the returned (generated) proxy should always inherit from a standard proxy base class?
So the ComponentContext method would be:


        virtual ServiceProxy * getService(const std::string& referenceName) const = 0;


I like this better as I have a personal hatred of void* ;-)


Cheers,


Pete Robbins

Phone: UK (01962) 818667
Notes: Pete Robbins/UK/IBM@IBMGB
email: robbins@uk.ibm.com

Bryan Aupperle <aupperle@us.ibm.com>

13/02/2009 19:12

 

To

sca-c-cpp@lists.oasis-open.org

cc

 

Subject

RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++


 

 

 

 






I have a slight preference for (1) over (2) (even though it is more spec work).  If the concrete implementation is returned by a getService call, then the SCA runtime should not know when control is passed from one component to the next and a getCurrent() is likely to return the wrong context.  Further, even if the client and service are in the same process, if the service's interface is remotable, the appropriate marshalling/unmarshalling has to be done.


Having said that, I would only generate the Async functions when necessary - which does mean the SCDL file have to be considered when generating code.


The base proxy class could be where the API for WiredByImpl is supported.  But if there was not a base proxy class, and async functions are only included when the asyncInvocation is present , would the proxy have to have its own header file?
Bryan Aupperle, Ph.D.
STSM, WebSphere Enterprise Platform Software Solution Architect

Research Triangle Park,  NC
+1 919-254-7508 (T/L 444-7508)
Internet Address: aupperle@us.ibm.com

"David Haney" <haney@roguewave.com>

02/13/2009 01:38 PM

 

 

To

Bryan Aupperle/Raleigh/IBM@IBMUS, <sca-c-cpp@lists.oasis-open.org>

cc

 

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.


David.


 


 





From:
Bryan Aupperle [mailto:aupperle@us.ibm.com]
Sent:
Friday, February 13, 2009 5:46 AM
To:
sca-c-cpp@lists.oasis-open.org
Subject:
RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++



I may be missing a bit of history here, but my understanding of the spec has always been that ComponentContext::getService() returned a proxy.  From section 3.1:

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"
#include "CustomerService.h"


using namespace oasis::sca;


void clientFunction()

{


unsigned long customerNumber = 1234;


ComponentContextPtr context = ComponentContext::getCurrent();


CustomerService* service =
                (CustomerService* )context->getService("customerService");


short rating = service->getCreditRating(customerNumber);


}


If the object returned by ComponentContext::getService() is not a generated proxy, then what is it?


Bryan Aupperle, Ph.D.
STSM, WebSphere Enterprise Platform Software Solution Architect

Research Triangle Park,  NC
+1 919-254-7508 (T/L 444-7508)
Internet Address: aupperle@us.ibm.com

"David Haney" <haney@roguewave.com>

02/12/2009 07:51 PM

 

 

To

Bryan Aupperle/Raleigh/IBM@IBMUS, <sca-c-cpp@lists.oasis-open.org>

cc

 

Subject

RE: [sca-c-cpp] ISSUE 54: Long Running Operations and C++




 

 

 

 

 




An issue came up when revising this document to take an IOU/Future approach to the asynchronous interface.  With the introduction of the asynchronous functions, we’ve also introduced the concept of a service proxy class, which I don’t think has been mentioned before.  This appears to be a code generated class, based on either the WSDL or C++ interface for the service, and it looks like it will be this class that is returned from the ComponentContext::getService() and presumably the ExternalContext::getService().  This seems like a relatively significant change from what we’ve discussed before, and may have wider reaching implications than just the asynchronous API.  For example, if we’re now requiring code generation of a proxy class for all services, then we no longer have a requirement that the ComponentContext::getService() method return a type without a base class.  We could require that all generated proxy classes derive from some sort of base Proxy class.  This would allow us to provide a type safe mechanism for accessing the proxies, instead of the unsafe mechanism we have today:


oasis::sca::ComponentContextPtr context = oasis::sca::ComponentContext::getCurrent();

MyServiceProxy* proxy = dynamic_cast<MyServiceProxy*>(context->getService(“MyService”));


proxy will be null if the service we get back isn’t a MyServiceProxy.  This only works though if all proxies (and all services returned from MyService) inherit from a common base class.


If we are introducing the generation of a proxy concept, we also probably need to expand the current WSDL mapping rules and clarify how we map from a WSDL to a generated proxy.


Thanks.


David.


 






From:
Bryan Aupperle [mailto:aupperle@us.ibm.com]
Sent:
Friday, February 06, 2009 12:36 PM
To:
sca-c-cpp@lists.oasis-open.org
Subject:
[sca-c-cpp] ISSUE 54: Long Running Operations and C++



This is a fairly complete proposal
The one topic that is open is how to deal with operations that have multiple possible WSDL faults.  Do we need to define a ServiceBusinessException class that the classes generated from a WSDL document extend?


Bryan Aupperle, Ph.D.
STSM, WebSphere Enterprise Platform Software Solution Architect

Research Triangle Park,  NC
+1 919-254-7508 (T/L 444-7508)
Internet Address: aupperle@us.ibm.com
[attachment "sca-cppcni-1.1-spec-cd02+Issue54a-rev2.doc" deleted by Bryan Aupperle/Raleigh/IBM] ---------------------------------------------------------------------
To unsubscribe from this mail list, you must leave the OASIS TC that
generates this mail.  Follow this link to all your TCs in OASIS at:
https://www.oasis-open.org/apps/org/workgroup/portal/my_workgroups.php

sca-cppcni-1 1-spec-cd02+Issue54c.doc



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]