
Hi all, I've searched this list a bit and found a few mentions of rpc's (Remote Procedure Call), but nothing concrete. I've written a library for doing portable C++ RPC's, which can be downloaded at http://www.codeproject.com/threads/RMI_For_Cpp.asp Is there any interest in Boost for something like this, and if so in what directions do you all think it should be developed? Thanks! Jarl.

"Jarl Lindrud" <jlindrud@hotmail.com> wrote in message news:loom.20050301T145733-176@post.gmane.org... | | Hi all, | | I've searched this list a bit and found a few mentions of rpc's (Remote | Procedure Call), but nothing concrete. | | I've written a library for doing portable C++ RPC's, which can be downloaded at | | http://www.codeproject.com/threads/RMI_For_Cpp.asp | | Is there any interest in Boost for something like this, and if so in what | directions do you all think it should be developed? This looks very intersting. I think there would be a general interest in most kinds of networking utilities...standard methods are really lacking in C++. I think the standard comittee would see favuorable to proposals related to networking. Your library seems fairly simple to use. I'm wondering though if the the macros can be avoided? I don't know how much code is hidden in them. but maybe a different approach vould be used so they disappeared entirely. As for performance, then I think the interface should be your first priority. (But if you happen to know why serialization with boost is so much slower, I think most of us would be interested to know that too :-) br -Thorsten

Jarl Lindrud wrote:
Hi all,
I've searched this list a bit and found a few mentions of rpc's (Remote Procedure Call), but nothing concrete.
I've written a library for doing portable C++ RPC's, which can be downloaded at
http://www.codeproject.com/threads/RMI_For_Cpp.asp
Is there any interest in Boost for something like this, and if so in what directions do you all think it should be developed?
I just looked briefly, and I am intrigued by the possibility that this functionality could be integrated with the (unofficial) Boost Interfaces library. http://www.kangaroologic.com/interfaces/ On my todo list is runtime reflection for interfaces, which I've been thinking might eventually form part of an RPC mechanism, together with Boost.Serialization. See http://tinyurl.com/6z55h You're interface definitions look a lot like Boost IDL definitions: http://www.kangaroologic.com/interfaces/libs/interfaces/doc/index.html?path=... What kind of code needs to be generated by the macros to support your framework? Jonathan

On my todo list is runtime reflection for interfaces, which I've been thinking might eventually form part of an RPC mechanism, together with Boost.Serialization. See
The thought's been on my mind as well...
You're interface definitions look a lot like Boost IDL definitions:
http://www.kangaroologic.com/interfaces/libs/interfaces/doc/index.html?path=....
2
What kind of code needs to be generated by the macros to support your
framework?
Jonathan
You can see the macro definitions in the include/Idl.hpp file, it's mainly code to generate dispatch ID's, to invoke marshaling of arguments, and to invoke target member functions. If it could all be subsumed under BOOST_IDL, that would be great. /Jarl.

Jarl Lindrud wrote:
What kind of code needs to be generated by the macros to support your framework?
You can see the macro definitions in the include/Idl.hpp file,
I know -- I was hoping you'd give me the Cliff Notes version ;-)
it's mainly code to generate dispatch ID's, to invoke marshaling of arguments, and to invoke target member functions.
Okay, thanks.
If it could all be subsumed under BOOST_IDL, that would be great.
Thanks, I think I will try to do this in the next revision. I'd like to make underlying transport mechanism pluggable, so people can implement other IPC mechanisms. BTW, don't tell anyone, but I'm implementing OpenSSL wrappers for the iostreams library, which might be used for the socket interface. One last point is that Boost.Interfaces is not as portable as your current implementation. For example, it works on GCC 3.4 but not GCC 3.2. When the design is finished I will work on porting it to some currently unsupported platforms, but there are limits: it will never work on Borland 5.x, for instance.
/Jarl.
Jonathan

Jonathan Turkanis <technews <at> kangaroologic.com> writes:
I'd like to make underlying transport mechanism pluggable, so people can implement other IPC mechanisms.
BTW, don't tell anyone, but I'm implementing OpenSSL wrappers for the
iostreams
library, which might be used for the socket interface.
I'm working on factoring out the transport mechanism, mainly because I want to be able to use asynchronous networking (I/O completion ports on Windows). iostreams don't mesh too well with async i/o though, so I'm not sure that that's the best place for the SSL stage, I'd rather have it bound up with the transport mechanism. I've found it more practical to keep the transport completely separate from any iostreams; once a chunk of data has arrived, just construct a stringstream on top of it.
One last point is that Boost.Interfaces is not as portable as your current implementation. For example, it works on GCC 3.4 but not GCC 3.2. When the design is finished I will work on porting it to some currently unsupported platforms, but there are limits: it will never work on Borland 5.x, for instance.
Jonathan
But then Borland 5.x is a seriously bugridden compiler.... 95% of my porting problems were with that compiler. :) Jarl.

Jarl Lindrud wrote:
Jonathan Turkanis <technews <at> kangaroologic.com> writes:
I'd like to make underlying transport mechanism pluggable, so people can implement other IPC mechanisms.
BTW, don't tell anyone, but I'm implementing OpenSSL wrappers for the iostreams library, which might be used for the socket interface.
I'm working on factoring out the transport mechanism, mainly because I want to be able to use asynchronous networking (I/O completion ports on Windows). iostreams don't mesh too well with async i/o though, so I'm not sure that that's the best place for the SSL stage,
Unfortunately, "iostreams" is not really the best name for the iostreams library. "io" would have been better, but it was already taken. The devices provided by the iostreams library, such as memory mapped files, can be used independently of std C++ iostreams, which as you say don't work too well with non-blocking or async i/o. The first version of iostreams will support non-blocking i/o. I'm planning to introduce asynchronous device concepts at some point, but haven't done so yet.
I'd rather have it bound up with the transport mechanism.
Okay.
I've found it more practical to keep the transport completely separate from any iostreams; once a chunk of data has arrived, just construct a stringstream on top of it.
One last point is that Boost.Interfaces is not as portable as your current implementation. For example, it works on GCC 3.4 but not GCC 3.2. When the design is finished I will work on porting it to some currently unsupported platforms, but there are limits: it will never work on Borland 5.x, for instance.
But then Borland 5.x is a seriously bugridden compiler.... 95% of my porting problems were with that compiler. :)
Tell me about it!! ;-)
Jarl.
Jonathan

Jonathan Turkanis wrote:
But then Borland 5.x is a seriously bugridden compiler.... 95% of my porting problems were with that compiler. :)
Tell me about it!! ;-)
Borland have now commited to another version of C++Builder. The compiler is going to receive updates, including using DinkumWare for the STL. They haven't promised how much will be fixed, but they have stated that libraries such as boost and loki are targets for them. We also don't have an idea of a time-frame yet. Cheers Russell

Russell Hind wrote:
Jonathan Turkanis wrote:
But then Borland 5.x is a seriously bugridden compiler.... 95% of my porting problems were with that compiler. :)
Tell me about it!! ;-)
Borland have now commited to another version of C++Builder. The compiler is going to receive updates, including using DinkumWare for the STL.
Do you mean that the 5.x compiler will receive updates, or are you talking about the EDG-based compiler? Jonathan

Jonathan Turkanis wrote:
Do you mean that the 5.x compiler will receive updates, or are you talking about the EDG-based compiler?
The EDG compiler is on hold indefinitely (unfortunately), so it will be an updated 5.x. We just don't know how updated. Apart from using DinkumWare, specific fixes haven't been mentioned although Borland employess are now traweling through qc (http://qc.borland.com/) opening up bug reports that have been made over the last 2-3 years since BCB6 (bcc32-5.6.4) was released. Have a look at http://bdn.borland.com/article/0,1410,32958,00.html for a little bit more info (although not a whole lot yet, mostly about BCB as an IDE, not the compiler itself) Cheers Russell

Russell Hind wrote:
Jonathan Turkanis wrote:
Do you mean that the 5.x compiler will receive updates, or are you talking about the EDG-based compiler?
The EDG compiler is on hold indefinitely (unfortunately),
I was afraid of that :(
so it will be an updated 5.x. We just don't know how updated.
Looks like I may have to rewrite a lot of guards of the form #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) ;-) Anway, I'm happy to hear that there will be updates.
Apart from using DinkumWare, specific fixes haven't been mentioned although Borland employess are now traweling through qc (http://qc.borland.com/) opening up bug reports that have been made over the last 2-3 years since BCB6 (bcc32-5.6.4) was released.
Have a look at
http://bdn.borland.com/article/0,1410,32958,00.html
for a little bit more info (although not a whole lot yet, mostly about BCB as an IDE, not the compiler itself)
Thanks! Jonathan

"Jarl Lindrud" wrote:
I've written a library for doing portable C++ RPC's, which can be downloaded at
http://www.codeproject.com/threads/RMI_For_Cpp.asp
Is there any interest in Boost for something like this, and if so in what directions do you all think it should be developed?
Yes. Would it be possible to use the library as communication channel between isolated threads, like it is in language Erlang (http://www.erlang.org/)? Erlang provides very easy to use and very powerful way to create (completely isolated) processes (actually threads), send messages between them and manage their lifetime. All location transparent. As result design of an Erlang app could be separated into small processes of natural "size". I only wish something similar in C++. ------------ More details: - Erlang can easily start processes locally: pid = spawn(AFunction, Parameters) or on different node pid = spawn(Node, AFunction, Parameters) - error happening in "child" process causes parent process to be stopped (this is feature but parent may handle error) - processes can be monitored whether they are alive yet - new version of a process may be loaded into running app automatically and transparently (Erlang is functional language w/o state so this is relatively easy) - the data passed between processes are all values with attached metadata for checking. This enables high isolation, avoids locking and allows to create systems with tens of thousands of processes (threads) /Pavel

Pavel Vozenilek <pavel_vozenilek <at> hotmail.com> writes:
"Jarl Lindrud" wrote:
I've written a library for doing portable C++ RPC's, which can be downloaded at
http://www.codeproject.com/threads/RMI_For_Cpp.asp
Is there any interest in Boost for something like this, and if so in what directions do you all think it should be developed?
Yes.
Would it be possible to use the library as communication channel between isolated threads, like it is in language Erlang (http://www.erlang.org/)?
I'm not familiar with Erlang, but certainly one could set things up so that every thread listens on a port of its own, and only communicates with other threads by sending messages (one-way rpc's). The syntax would be pretty clean, I think. /Jarl

"Jarl Lindrud" <jlindrud@hotmail.com> wrote
I've written a library for doing portable C++ RPC's, which can be downloaded at
http://www.codeproject.com/threads/RMI_For_Cpp.asp
Is there any interest in Boost for something like this, and if so in what directions do you all think it should be developed?
Unfortunately I am not really current on the subject... However, a few years ago I was reading an XML book by Don Box (one of the leading COM people). I didn't really like the book, unlike "Essential COM", which was one of my favorites. However one thing I remember, and totally agree with, was his perception of RPC. He argued that faking function calls is quite dangerous, since it is really hiding from the user what's going on, and so may (and often does) cause wrong design decisions to be made, since we all tend to ignore the cost of a function call. Quite an interesting statement from a person who built most of his career around RPC, marshalling, etc. Maybe a better way to go would be creating a more low-level, messaging library, that would simplify inter-process/thread communication, but would not attempt to make it look like function calls? Regards, Arkadiy

"Jarl Lindrud" <jlindrud@hotmail.com> wrote in message news:loom.20050301T145733-176@post.gmane.org...
Hi all,
I've searched this list a bit and found a few mentions of rpc's (Remote Procedure Call), but nothing concrete.
I've written a library for doing portable C++ RPC's, which can be downloaded at
http://www.codeproject.com/threads/RMI_For_Cpp.asp
Is there any interest in Boost for something like this, and if so in what directions do you all think it should be developed?
I'd definitely be interested by portable, standard, simple-to-use C++-based remoting of objects. Just a couple of quick questions after scanning the article: - Does/could the library support custom marshaling on a per-object and/or interface basis - I'd be specifically interested in MBV (Marshal By Value)? - Did you implement portable, binary serialization? // Johan

Johan Nilsson <johan.nilsson <at> esrange.ssc.se> writes:
Just a couple of quick questions after scanning the article:
- Does/could the library support custom marshaling on a per-object and/or interface basis - I'd be specifically interested in MBV (Marshal By Value)? - Did you implement portable, binary serialization?
// Johan
I think it would be relatively straightforward to support something like MBV. The machinery is already there, it would just need to be applied a bit differently. Yeah, I implemented portable binary serialization, along with native binary and text serialization. I had some performance issues with boost serialization, it seems as if the boost archives are not well optimized to what I'm doing, which is creating thousands of archives per second, and then serializing a small amount of data to/from them. I haven't looked closely enough yet to say where the bottleneck is, though. /Jarl.

"Jarl Lindrud" <jlindrud@hotmail.com> wrote in message news:loom.20050302T105454-130@post.gmane.org...
Johan Nilsson <johan.nilsson <at> esrange.ssc.se> writes:
Just a couple of quick questions after scanning the article:
- Does/could the library support custom marshaling on a per-object and/or interface basis - I'd be specifically interested in MBV (Marshal By Value)? - Did you implement portable, binary serialization?
// Johan
I think it would be relatively straightforward to support something like MBV. The machinery is already there, it would just need to be applied a bit differently.
Sorry for not taking the time to read through the implementation, but I have another couple of questions: - Is it possible to return an interface as an [out] parameter, receiving a proxy to a remoted object? - Is it possible to pass an interface as an [in] parameter, having the receiver receive a proxy to the original object? - Did you consider implement cross-process reference counted lifetime management (ala DCOM)? - Did you consider specific support for cross-apartment marshalling (sorry for all DCOM terms, but that's what I've been using in the past)? That is, did you consider different threading models, so that single threaded applications only would receive callbacks in the context of the main thread?
Yeah, I implemented portable binary serialization, along with native binary and text serialization. I had some performance issues with boost serialization, it seems as if the boost archives are not well optimized to what I'm doing, which is creating thousands of archives per second, and then serializing a small amount of data to/from them. I haven't looked closely enough yet to say where the bottleneck is, though.
Lastly, are these implementations available in the download and, under what kind of license is the current implementation distributed (I'd like to try it out in a current in-house project)? / Johan

Johan Nilsson <johan.nilsson <at> esrange.ssc.se> writes:
Sorry for not taking the time to read through the implementation, but I have another couple of questions:
- Is it possible to return an interface as an [out] parameter, receiving a proxy to a remoted object?
- Is it possible to pass an interface as an [in] parameter, having the receiver receive a proxy to the original object?
Both are possible. The RcfClient<> class derives from the RCF::ClientStub class, which contains all the information needed to connect to a specific object (object id, ip, port, etc), so the only thing that needs to be done is to tell the serialization engine how to handle RcfClient<>'s. Eg template<typename Archive> void serialize(Archive &ar, RcfClient<MyInterface> &c, const unsigned int) { serializeParent<RCF::ClientStub>(ar, *this); } In fact, in the next release I'll have that done automatically as part of defining the interface.
- Did you consider implement cross-process reference counted lifetime management (ala DCOM)?
I'm not sure that the reference counting semantics of DCOM are one of its better points... Requiring a remote client to correctly call AddRef() and Release() is pretty fragile, IMO. For now, what I've done is that each object keeps track of how many connections are currently connected to it, and when the count reaches zero, a timeout is set, and if the timeout expires with no more connections, then the object is removed. The RcfClient<> class automatically terminates connections when it's destroyed, so as long as you allocate clients on the stack it works pretty well.
- Did you consider specific support for cross-apartment marshalling (sorry for all DCOM terms, but that's what I've been using in the past)? That is, did you consider different threading models, so that single threaded applications only would receive callbacks in the context of the main thread?
I haven't considered it, but I just got the same request from another user, so I guess it's time to do so... It might be a little messy, and to me it doesn't seem very natural. But I realize sometimes its necessary for application specific reasons to have client requests handled by a specific user-prepared thread, and not just a generic worker thread.
Yeah, I implemented portable binary serialization, along with native binary and text serialization. I had some performance issues with boost serialization, it seems as if the boost archives are not well optimized to what I'm doing, which is creating thousands of archives per second, and then serializing a small amount of data to/from them. I haven't looked closely enough yet to say where the bottleneck is, though.
Lastly, are these implementations available in the download and, under what kind of license is the current implementation distributed (I'd like to try it out in a current in-house project)?
The alternative serialization system isn't included in the current download, but I'll be posting an update soon, with it included. I haven't given very much thought to the license, but you're more than welcome to use it, just keep me posted on how it works out! If you need something more formal, there's a licence under which all CodeProject articles fall, I couldn't find it now, but basically you're free to use it as long as the copyright notices are not removed, IIRC. HTH, Jarl.

"Jarl Lindrud" wrote:
- Is it possible to return an interface as an [out] parameter, receiving a proxy to a remoted object?
- Is it possible to pass an interface as an [in] parameter, having the receiver receive a proxy to the original object?
Both are possible.
H. S. Lahman list available options and argues that passing anything else than values is dangerous and causes high coupling: http://groups.google.ca/groups?selm=3B86C364.AB1A6066%40worldnet.att.net (the paragraphs starting with "pure message"). Maybe the library could have something as safe mode enabled by macro (RPC_ONLY_SAFE_FUNCTIONALITY). Erlang, for example, has only asynchronous messages with passing of values. The language is (technological) success and this "limitation" was quoted as one of reasons (it makes deadlocks hard, frex).
- Did you consider implement cross-process reference counted lifetime management (ala DCOM)?
I'm not sure that the reference counting semantics of DCOM are one of its better points... Requiring a remote client to correctly call AddRef() and Release() is pretty fragile, IMO.
Yes. Counting semantic is usability mistake, at least according to: http://www.relisoft.com/win32/olerant.html /Pavel

"Pavel Vozenilek" <pavel_vozenilek@hotmail.com> wrote in message news:d07hih$veg$1@sea.gmane.org...
"Jarl Lindrud" wrote:
- Is it possible to return an interface as an [out] parameter, receiving a proxy to a remoted object?
- Is it possible to pass an interface as an [in] parameter, having the receiver receive a proxy to the original object?
Both are possible.
H. S. Lahman list available options and argues that passing anything else than values is dangerous and causes high coupling: http://groups.google.ca/groups?selm=3B86C364.AB1A6066%40worldnet.att.net (the paragraphs starting with "pure message").
If you use well-defined interfaces I can't see how that would cause any higher coupling than during normal circumstances (remoting aside). A pretty common usage would be implementing the Observer pattern cross-process. [snip]
Yes. Counting semantic is usability mistake, at least according to: http://www.relisoft.com/win32/olerant.html
That's a rant alright, which would seem to include shared_ptr's as well - or? // Johan

"Johan Nilsson" wrote:
H. S. Lahman list available options and argues that passing anything else than values is dangerous and causes high coupling: http://groups.google.ca/groups?selm=3B86C364.AB1A6066%40worldnet.att.net (the paragraphs starting with "pure message").
If you use well-defined interfaces I can't see how that would cause any higher coupling than during normal circumstances (remoting aside). A pretty common usage would be implementing the Observer pattern cross-process.
What I mean is: I am interface A and I call interface B. I pass interface C and B will call C. Now B needs to handle all possible C exceptions. Some exceptions may be passed back to A (depending on implementation). Now also A needs to know about C and how to deal with its problems. If there are only asynchronously passed values one needs to guard timeouts and watch internal state machine of A correct. Added complexity in B, C, ... doesn't spill (much) into A. /Pavel
participants (7)
-
Arkadiy Vertleyb
-
Jarl Lindrud
-
Johan Nilsson
-
Jonathan Turkanis
-
Pavel Vozenilek
-
Russell Hind
-
Thorsten Ottosen