Boost logo

Boost :

Subject: Re: [boost] Interest in Remote Procedure Call Library?
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2010-02-07 21:29:13


On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
>        Thanks for offering your code.  I can appreciate the desire not to use macros, but I believe that carefully used they can make a world of difference to the end user and eliminate many kinds of "typo bugs" that don't show up until runtime.

Oh, it is not a desire to not use macros, it is just that they were
unnecessary in that design. I use macros all the time, have no qualms
about that, the preprocessor is my friend. :)

That is the thing about my design, there is no need to reflect
anything, it used the function type decomposed into an mpl vector
(Boost.Function_traits) which then built up a recursive callback
(Boost.Fusion) to create a standalone callback function that handle
everything from base function calling to (de)serialization (more
Boost.Fusion), all with the single call to register, which its
signature is something like this:

template<typename FunctionType>
RPCHandler::type_of_callback<FunctionType>
RPCHandler::register(FunctionType func);

Internally it built up recursive templated callback (which was
optimized rather completely out into a single function call), of which
all power was done at compile time, type-checking, everything. There
was just no need for macro's at all. A reflection system of any sort
is rather worthless for this.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> Since I am new to this list, I will try not to foist to much of my "world view" on how an API should be developed, but I firmly believe that syntax matters and that the end user (average C++ college grads who know little of templates, member function pointers, etc) can use the API.  At my company I am the resident expert in C++ and working with a bunch of mechanical engineers whom I have been teaching C++ "on the job".  So I prefer the macros.  If there is some amazing way to achieve the same without macros then I will support it.  But nothing keeps the reflection synchronized with method names better than a macro.

Exactly, I love simple syntax, that is why my system required just one
line of code to register an RPC call, whether a standalone function,
or a simple/complex, short/long-lived class. No need to reflect
anything, no huge amounts of code. See my example above, it is very
short, *very* efficient, easy to use, and has been in heavy use for
multiple years now in a variety of products, including some class A
games.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> Certainty the macro's should just build upon the "real API" and thus there should be some considerable effort made to make the "real api" as friendly as possible.  Unfortunately, I am not as skilled with the pre-processor as I would like to be and so often my limited ability to manipulate tokens with the pre-processor is compensated for by code structure.

Exactly. I actually did have one macro in mine, it was just something
like this though:
  #define REGISTER_RPC(RPC, FUNC, NAME)
RPCHandler::type_of_callback<FUNC> NAME = global_rpc.register(FUNC,
#NAME);
Or something like that, just cut out the short amount of typing to
something shorter, but it was completely unnecessary.

> Perhaps the discussion on what should be in an RPC library should begin with requirements.
>
> 1) Minimize code/syntax required to expose a class to the "transport"

Exactly, mine requires one line of code per exposed function, yours
requires more, I am still not sure why you need to reflect it...

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 2) Ability to expose any number of methods (overloaded or not)

Yep, mine supports any number, including overloaded ones with no issue.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 3) Fully support multiple/virtual inheritance of interfaces

Yep, mine supports that with absolutely no problem as well.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 4) Support Boost.Signals

I do not see why mine would have any problems with this, but untested,
just a simple functor call so it should work with no problem.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 5) Support Boost.Serialization
>        - on this note, I have some concern over performance and "predictability" for interfacing with other code not using Boost.Serialization.

Mine uses Boost.Serialization for my network version, a custom-made
thing for my script link, and RakNet::Bitstream for my RakNet version,
it is very easy to replace that at will.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 6) Ability to implement any "protocol" (TCP/UDP/SharedMemory/SOAP/etc)

Yep, mine uses Boost.ASIO by default (thus it support
TCP/UDP/SharedMemory/etc... out of the box), and mine supports an
interface into my little scripting, and mine supports interfacing into
the highly efficient RakNet networking library, so yes, it is very
easy to implement other things on top of it.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 7) Support for exceptions
>        - this requires a factory that is able to dynamically create the exception type from serialized data.  Normal return values do not need this because it is known at compile time what the serialization of the return type is; however, with exceptions it could be "anything".  For this I have used boost::any combined with a 32 bit hash of the class name.

Mine does not support return types, mine is purely asynchronous, so
this is not implemented, however if futures or callbacks or so were
implemented (I hate synchronous network calls with a passion, so do
not expect me to ever make such a thing, callbacks and futures for
sure! someone else could add it though), then it might be worth it to
set such a thing up, although I see an easier way of doing it thanks
to Boost.Fusion that would not require a factory and would be more
efficient (have this idea thanks to my work in Boost.Spirit oddly
enough, Joel and Hartmut are awesome).

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> 8) Some kind of minimum performance metric? In my opinion the library should perform on par with the best RPC libraries available only provide a simple, cross-platofrm, c++ native solution and not depend upon code generation.

Mine was made for pure efficiency. RakNet already had an RPC system
(two actually), mine replaced both due to a few things, it executed
faster, it was type-safe, it was more powerful, it allowed for passing
RPC related data easier, etc.. Thus, mine is purely cross-platform
(RakNet runs on a lot of systems), purely C++ native, no code
generation or anything, pure C++ template work.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> As an added bonus, the same system should work to expose any object to any scripting engine because all of the required meta-information would be available.

I am not sure what meta-information you are talking about, but as
stated, I originally made mine as an RPC callback system into a little
scripting language.

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> In reality there are two libraries here.  One for RPC and one for "reflection" and creation of
> proxy objects.  The reflection library could use some of the features of Boost.Mirror instead of its own mechanism for getting the name of a type:

I do not see how RPC and reflection overlap though, at all, should
those not be split into two libraries?

On Sun, Feb 7, 2010 at 6:26 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> Clearly the idea of a reflection library in boost is not a new one.  What are the main drivers that have prevented any of the proposed reflection techniques from being adopted?   Is there anything I am doing / proposing that is clearly taboo for boost libraries?

I am curious about this too, a good reflection system for C++ (I still
have no clue why it does not have one built-in, would simplify so much
of Boost's work) would be quite useful, but I still wonder why you
have one in an RPC library.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk