|
|
|
|||||
|
Ice Proxy Design
Hi,
In the process of coming up to speed on Ice (and some CORBA), I've run into a couple of issues about which I'm hoping to get a little clarification. First, I was a little surprised that Ice (and apparently CORBA too) doesn't seem to apply the Proxy pattern as it's usually described (by the GoF, for example). Specifically, why doesn't the Slice compiler generate a common base from which the proxy and servant classes are both derived? I assumed (perhaps naively) that the ability to write client code which remains unaware of whether it's dispatching to a proxy or a real subject (i.e, servant) would be important. Second, I was pleased to read early in the Ice Book that the Slice 'nonmutating' keyword facilitates use of the C++ 'const' keyword for the corresponding class member functions generated by the Slice compiler. But AFAICT, this translation is only applied for the servant class interface and not for the proxy. If I'm right about that, this means client-side APIs that depend on proxy interfaces must either avoid 'const' altogether or use const_cast everywhere. That seems like an unfortunate liability. Thanks, Greg |
|
||||||
|
For the first part of your question, please have a look at this thread:
Why Java proxies does not implement the slice interface ? The short answer is, in order to have a flexible distributed system, there can be no is-a relationship between a proxy and the servant. An invocation on a proxy is fundamentally different than an invocation on the servant itself. Trying to hide these fundamental differences destroys both location and implementation transparency. Note that older CORBA ORBs used an is-a relationship between proxy and servant, but because of the serious drawbacks of this design, newer CORBA standards explicitly mandated to not use this approach. As for the second part of your question, you cannot translate nonmutating into const proxy operations, because by invoking on a proxy, the state of the proxy can change (for example, it might establish a new connection), regardless of whether the operation is nonmutating or not. |
|
|||||
|
I admit to being new to distributed computing and that there are many issues I'm unaware of, but it's not readily apparent to me how GoF-style proxies would destroy location or implementation transparency. Quite the opposite:
Code:
client ---> interface
/ \
proxy --> servant
The way it looks to me, Ice proxies aren't as effective as they could be when it comes to making location transparent precisely because they don't derive from the same abstract base as the servant. If location were truly transparent, much (most?) client code would be blissfully unaware of whether it's dispatching to a proxy or an actual servant. For that kind of code, whether the target object resides outside the client's address space should be an implementation detail that has nothing to do with its logical interface. In which case, if an operation is defined on an application interface as 'const', that operation should remain logically 'const' whether it's intercepted by a proxy or implemented by a servant. On a related note, the Ice Book often uses Coplien's "ambassador" terminology when describing the semantics of proxies. Note that, when Coplien says "the difference is transparent to the caller invoking the service" regardless of whether the caller is on the same processor as the "body", the transparency he refers to in his example can only realistically be achieved by deriving the proxy and servant bodies from a common interface. |
|
||||||
|
Please read the various posts that have already been written about this subject, and read the documentation about the relationship between Ice object, proxy, and servant. If this is too abstract, then please have a look at the documentation for servant locators, and also at the documentation for the Freeze evictor (which is one concrete implementation of a servant locator).
You cannot have an is-a relationship between a proxy and a servant, because a proxy is-not a servant, and a servant is-not an Ice object. Instead, proxies allows you to invoke on Ice objects, and servants implement Ice objects. For example, if you invoke on a proxy, a servant might not even exist yet for the Ice object, but may be loaded on demand by a servant locator. In fact, several different Ice objects (with different proxies) might even use only one single servant. This is then called a default servant. Or there might be several servants for one Ice object to implement an Ice object redundantly. The point is, no matter how an Ice object is implemented, you must always be able to use a proxy to invoke on this Ice object, without having to be aware of the implementation details. That's called implementation transparency. And this must work regardless of whether the servant is collocated or not. That's called location transparency. It is important to understand that a proxy is a proxy for an Ice object, and not for a servant. As I wrote above, a servant is used to implement Ice objects, but it is not an Ice object. An Ice object is not a concrete language construct, but a concept for the development of scalable distributed applications. Therefore an Ice proxy is not the same as the GoF proxy. As an aside, you often cannot apply the GoF patterns 1:1 to distributed systems. For example, if you implement the Observer pattern exactly as described, you will run into deadlock problems. The last issue #4 of Connections has an article about this. Last edited by marc : 07-28-2005 at 07:40 PM. |
|
|||||
|
Marc wrote:
Quote:
Marc wrote: Quote:
Marc wrote: Quote:
Marc wrote: Quote:
Marc wrote: Quote:
I'm (i.e., the company I work for) in the early stages of developing a distributed system, so I'm trying to understand how Ice (and CORBA for that matter) works and whether it will suit our needs. The Slice-to-C++ standard library binding, exception inheritance, UDP support, threading constructs, IceStorm and Freeze are all big wins, but the fact that I can't swap proxies for servants GoF-style when I know a priori that it's desirable to do so seems unfortunate. Perhaps I could build wrappers to do this instead. -Greg |
|
||||||
|
Hi Greg,
pretty much all the pre-POA CORBA ORBs (Visibroker, Orbix, Orbacus 1, etc) used the same hierarchy for the client and server side. With the POA, the client- and server-side APIs were split because not doing so caused problems. Ice follows the same philosophy. Here are some of the reasons:
Quote:
Whether a servant is collocated or not, by always invoking on a proxy, the same single programming model applies regardless of location: I invoke on the proxy, which somehow sends the invocation to the Ice object. If the Ice object does not exist, I get an ObjectNotExistException (instead of undefined behavior); if the Ice object exists, the invocation succeeds. If the Ice object cannot be reached, I get a ConnectionRefusedException or similar. Note that all of this is completely independent of whether a servant exists or not. In fact, the Ice object model has no notion of a servant at all: the object model only understands proxies and Ice objects. This is evidenced by the Slice type system: it is impossible to talk about servants in Slice. All you can talk about are proxies and interfaces; instances of interfaces are Ice objects, and proxies are pointers to these Ice objects. A servant is a server-side implementation artifact and the concept of "servant" simply has no meaning for the client side. In order to preserve the separation of interface and implementation, it follows that there must be no way for client-side code to have any notion of a servant, because servants simply do not exist in the client-side programming model. But, by deriving the proxy and the servant from a common base, we would allow the server-side implementation artifact to spill over into the client-side programming model and lose this separation. Cheers, Michi. Last edited by michi : 07-30-2005 at 06:39 PM. |
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Java reflection / design issues | jelle | Help Center | 2 | 07-09-2006 08:42 PM |
| application structure /design | leyang | Help Center | 0 | 12-27-2004 09:23 AM |
| IcePatch design question | stephan | Help Center | 1 | 09-28-2004 05:00 PM |
| Design patterns for using CCM (related to IceBox) | SteveWampler | Help Center | 16 | 05-22-2004 11:53 PM |
| specific design question | sylvain | Help Center | 4 | 07-08-2003 07:28 PM |