Message receive for c++ actor system - c++

I am trying to implement message handling for actors in c++. The following code in scala is something I am trying to implement in c++
def receive = {
case Message1 =>{/* logic code */}
case Message2 =>{/* logic code */}
}
Thus the idea is to create a set of handler functions for the various message type and create a dispatch method to route the message to its appropiate message handler. All messages will extends the base message type.
What would be the best approach to solve this problem:
Maintain a Map(Message_type, function_pointer), the dispatch method will check the map and call the appropiate method. This mapping however needs to be done mannually in the Actor class.
I read this library, the lbrary is handling message exactly as I want to but I cant understand how they do pattern matching on the lambda fucntions created on line 56.
I would appreciate any suggestion or reading links that could get me closer to the solution of this problem.

Since you've already mentioned CAF: why do you want to implement your own actor library instead of using CAF? If you are writing the lib as an exercise, I suggest start reading libcaf_core/caf/match_case.hpp, libcaf_core/caf/on.hpp and libcaf_core/caf/detail/try_match.hpp. This is the "core" of CAF's pattern matching facility. Be warned, you will be looking at a lot of metaprogramming code. The code is meant to be read by C++ experts. It's definitely not a good place to learn the techniques.
I can outline what's going on, though.
CAF stores patterns as a list of match_case objects in detail::behavior_impl
You never get a pointer to either one as user
message_handler and behavior store a pointer to behavior_impl
Match cases can be generated differently:
Directly from callbacks/lambdas (trivial case)
Using a catch-all rule (via others >> ...)
Using the advanced on(...) >> ... notation
CAF can only match against tuples stored in message objects
"Emulates" (a subset of) reflections
Values and meta information (i.e. type information) are needed
For the matching itself, CAF simply iterates over the list of match_case objects
Try match the input with each case
Stop on first match (just like functional languages implement this)
We put a lot of effort into the pattern matching implementation to get a high-level and clean interface on the user's end. It's not easy, though. So, if you're doing this as an exercise, be warned that you need a lot of metaprogramming experience to understand the code.
In case you don't do this as an exercise, I would be interested why you think CAF does not cover your use case and maybe we can convince you to participate in its development rather than developing something else from scratch. ;)

Try to use sobjectizer (batteries included) or rotor(still experimental, but quite lightweight actor-like solution).

Related

framework/library for property-tree-like data structure with generic get/set-implementation?

I'm looking for a data structure which behaves similar to boost::property_tree but (optionally) leaves the get/set implementation for each value item to the developer.
You should be able to do something like this:
std::function<int(void)> f_foo = ...;
my_property_tree tree;
tree.register<int>("some.path.to.key", f_foo);
auto v1 = tree.get<int>("some.path.to.key"); // <-- calls f_foo
auto v2 = tree.get<int>("some.other.path"); // <-- some fallback or throws exception
I guess you could abuse property_tree for this but I haven't looked into the implementation yet and I would have a bad feeling about this unless I knew that this is an intended use case.
Writing a class that handles requests like val = tree.get("some.path.to.key") by calling a provided function doesn't look too hard in the first place but I can imagine a lot of special cases which would make this quite a bulky library.
Some extra features might be:
subtree-handling: not only handle terminal keys but forward certain subtrees to separate implementations. E.g.
tree.register("some.path.config", some_handler);
// calls some_handler.get<int>("network.hostname")
v = tree.get<int>("some.path.config.network.hostname");
search among values / keys
automatic type casting (like in boost::property_tree)
"path overloading", e.g. defaulting to a property_tree-implementation for paths without registered callback.
Is there a library that comes close to what I'm looking for? Has anyone made experiences with using boost::property_tree for this purpose? (E.g. by subclassing or putting special objects into the tree like described here)
After years of coding my own container classes I ended up just adopting QVariantMap. This way it pretty much behaves (and is as flexible as) python. Just one interface. Not for performance code though.
If you care to know, I really caved in for Qt as my de facto STL because:
Industry standard - used even in avionics and satellite software
It has been around for decades with little interface change (think about long term support)
It has excellent performance, awesome documentation and enormous user base.
Extensive feature set, way beyond the STL
Would an std::map do the job you are interested in?
Have you tried this approach?
I don't quite understand what you are trying to do. So please provide a domain example.
Cheers.
I have some home-cooked code that lets you register custom callbacks for each type in GitHub. It is quite basic and still missing most of the features you would like to have. I'm working on the second version, though. I'm finishing a helper structure that will do most of the job of making callbacks. Tell me if you're interested. Also, you could implement some of those features yourself, as the code to register callbacks is already done. It shouldn't be so difficult.
Using only provided data structures:
First, getters and setters are not native features to c++ you need to call the method one way or another. To make such behaviour occur you can overload assignment operator. I assume you also want to store POD data in your data structure as well.
So without knowing the type of the data you're "get"ting, the only option I can think of is to use boost::variant. But still, you have some overloading to do, and you need at least one assignment.
You can check out the documentation. It's pretty straight-forward and easy to understand.
http://www.boost.org/doc/libs/1_61_0/doc/html/variant/tutorial.html
Making your own data structures:
Alternatively, as Dani mentioned, you can come up with your own implementation and keep a register of overloaded methods and so on.
Best

How to make API names into variables for easier coding

I am looking for a way to turn some long and confusing API function names into shorter types to reduce the amount of typing and over all errors due to misspelling.
For example : I would like to take gtk_functionName(); and make it a variable like so. doThis = gtk_functionName;
Sometimes the code will have lots of repeating suffix. I want to know if I can take this g_signal_connect_ and turn it into this connect so I could just type connectswapped instead of g_signal_connect_swapped.
I am looking to do this in C\C++ but would be happy to know how its done in any language. I thought I had seen a code that did this before but I can not figure out what this would be called so searching for it has been fruitless.
I am sure this is possible and I am just not able to remember how its done.
I believe what you are wanting to do is apply the Facade Pattern, which is to present a simplified interface to a larger, more complex body of code.
What this basically means is you define your own simplified interfaces for the functionality you want. The implementation of these interfaces use the longer more complex packages you want to simplify. After that, the rest of your code use the simplified interfaces instead of the complex package directly.
void doThis (That *withThat) {
gtk_functionName(withThat->arg1, withThat->arg2 /* etc. */);
}

Parsing different xml messages. Versions

Say we want to Parse a XML messages to Business Objects. We split the process in two parts, namely:
-Parsing the XML messages to XML Grammar Objects.
-Transform XML Objects to Business Objects.
The first part is done automatically, generation a grammar object for each node.
The second part is done following the XML architecture so far. Example:
If we have the XML Message(Simplified):
<Main>
<ChildA>XYZ</ChildA>
<ChildB att1="0">
<InnerChild>YUK</InnerChild>
</ChildB>
</Main>
We could find the following classes:
DecodeMain(Calls DecodeChildA and B)
DecodeChildA
DecodeChildB(Calls DecodeInnerChild)
DecodeInnerChild
The main problem arrives when we need to handle versions of the same messages. Say we have a new version where only DecodeInnerChild changes(e.g.: We need to add an "a" at the end of the value)
It is really important that the solutions agile for further versions and as clean as possible. I considered the following options:
1)Simple Inheritance:Create two classes of DecodeInnerChild. One for each version.
Shortcomming: I will need to create different classes for every parent class to call the right one.
2)Version Parameter: Add to each method an Object with the version as a parameter. This way we will know what to do within each method according to each version.
Shortcoming: Not clean at all. The code of different versions is mixed.
3)Inheritance + Version Parameter: Create 2 classes with a base class for the common code for the nodes that directly changes (Like InnerChild) and add the version as a parameter in each method. When a node call the another class to decode the child object, it will use one or another class depending on the Version parameter.
4)Some kind of executor pattern(I do not know how to do it): Define at the start some kind of specifications object, where all the methods that are going to be used are indicated and I pass this object to a class that is in charge of execute them.
How would you do it? Other ideas are welcomed.
Thanks in advance. :)
How would you do it? Other ideas are welcomed.
Rather than parse XML myself I would as first step let something like CodesynthesisXSD to generate all needed classes for me and work on those. Later when performance or something becomes issue I would possibly start to look aound for more efficient parsers and if that is not fruitful only then i would start to design and write my own parser for specific case.
Edit:
Sorry, I should have been more specific :P, the first part is done
automatically, the whole code is generated from the XML schema.
OK, lets discuss then how to handle the usual situation that with evolution of software you will eventually have evolved input too. I put all silver bullets and magic wands on table here. If and what you implement of them is totally up to you.
Version attribute I have anyway with most things that I create. It is sane to have before backward-compatibility issue that can not be solved elegantly. Most importantly it achieves that when old software fails to parse newer input then it will produce complaint that makes immediately sense to everybody.
I usually also add some interface for converter. So old software can be equipped with converter from newer version of input when it fails to parse that. Also new software can use same converter to parse older input. Plus it is place where to plug converter from totally "alien" input. Win-win-win situation. ;)
On special case of minor change I would consider if it is cheap to make new DecodeInnerChild to be internally more flexible so accepts the value with or without that "a" in end as valid. In converter I have still to get rid of that "a" when converting for older versions.
Often what actually happens is that InnerChild does split and both versions will be used side-by-side. If there is sufficient behavioral difference between two InnerChilds then there is no point to avoid polymorphic InnerChilds. When polymorphism is added then indeed like you say in your 1) all containing classes that now have such polymorphic members have to be altered. Converter should usually on such cases either produce crippled InnerChild or forward to older version that the input is outside of their capabilities.

Design methods for multiple serialization targets/formats (not versions)

Whether as members, whether perhaps static, separate namespaces, via friend-s, via overloads even, or any other C++ language feature...
When facing the problem of supporting multiple/varying formats, maybe protocols or any other kind of targets for your types, what was the most flexible and maintainable approach?
Were there any conventions or clear cut winners?
A brief note why a particular approach helped would be great.
Thanks.
[ ProtoBufs like suggestions should not cut it for an upvote, no matter how flexible that particular impl might be :) ]
Reading through the already posted responses, I can only agree with a middle-tier approach.
Basically, in your original problem you have 2 distinct hierarchies:
n classes
m protocols
The naive use of a Visitor pattern (as much as I like it) will only lead to n*m methods... which is really gross and a gateway towards maintenance nightmare. I suppose you already noted it otherwise you would not ask!
The "obvious" target approach is to go for a n+m solution, where the 2 hierarchies are clearly separated. This of course introduces a middle-tier.
The idea is thus ObjectA -> MiddleTier -> Protocol1.
Basically, that's what Protocol Buffers does, though their problematic is different (from one language to another via a protocol).
It may be quite difficult to work out the middle-tier:
Performance issues: a "translation" phase add some overhead, and here you go from 1 to 2, this can be mitigated though, but you will have to work on it.
Compatibility issues: some protocols do not support recursion for example (xml or json do, edifact does not), so you may have to settle for a least-common approach or to work out ways of emulating such behaviors.
Personally, I would go for "reimplementing" the JSON language (which is extremely simple) into a C++ hierarchy:
int
strings
lists
dictionaries
Applying the Composite pattern to combine them.
Of course, that is the first step only. Now you have a framework, but you don't have your messages.
You should be able to specify a message in term of primitives (and really think about versionning right now, it's too late once you need another version). Note that the two approaches are valid:
In-code specification: your message is composed of primitives / other messages
Using a code generation script: this seems overkill there, but... for the sake of completion I thought I would mention it as I don't know how many messages you really need :)
On to the implementation:
Herb Sutter and Andrei Alexandrescu said in their C++ Coding Standards
Prefer non-member non-friend methods
This applies really well to the MiddleTier -> Protocol step > creates a Protocol1 class and then you can have:
Protocol1 myProtocol;
myProtocol << myMiddleTierMessage;
The use of operator<< for this kind of operation is well-known and very common. Furthermore, it gives you a very flexible approach: not all messages are required to implement all protocols.
The drawback is that it won't work for a dynamic choice of the output protocol. In this case, you might want to use a more flexible approach. After having tried various solutions, I settled for using a Strategy pattern with compile-time registration.
The idea is that I use a Singleton which holds a number of Functor objects. Each object is registered (in this case) for a particular Message - Protocol combination. This works pretty well in this situation.
Finally, for the BOM -> MiddleTier step, I would say that a particular instance of a Message should know how to build itself and should require the necessary objects as part of its constructor.
That of course only works if your messages are quite simple and may only be built from few combination of objects. If not, you might want a relatively empty constructor and various setters, but the first approach is usually sufficient.
Putting it all together.
// 1 - Your BOM
class Foo {};
class Bar {};
// 2 - Message class: GetUp
class GetUp
{
typedef enum {} State;
State m_state;
};
// 3 - Protocl class: SuperProt
class SuperProt: public Protocol
{
};
// 4 - GetUp to SuperProt serializer
class GetUp2SuperProt: public Serializer
{
};
// 5 - Let's use it
Foo foo;
Bar bar;
SuperProt sp;
GetUp getUp = GetUp(foo,bar);
MyMessage2ProtBase.serialize(sp, getUp); // use GetUp2SuperProt inside
If you need many output formats for many classes, I would try to make it a n + m problem instead of an n * m problem. The first way I come to think of is to have the classes reductible to some kind of dictionary, and then have a method to serlalize those dictionarys to each output formats.
Assuming you have full access to the classes that must be serialized. You need to add some form of reflection to the classes (probably including an abstract factory). There are two ways to do this: 1) a common base class or 2) a "traits" struct. Then you can write your encoders/decoders in relation to the base class/traits struct.
Alternatively, you could require that the class provide a function to export itself to a container of boost::any and provide a constructor that takes a boost::any container as its only parameter. It should be simple to write a serialization function to many different formats if your source data is stored in a map of boost::any objects.
That's two ways I might approach this. It would depend highly on the similarity of the classes to be serialized and on the diversity of target formats which of the above methods I would choose.
I used OpenH323 (famous enough for VoIP developers) library for long enough term to build number of application related to VoIP starting from low density answering machine and up to 32xE1 border controller. Of course it had major rework so I knew almost anything about this library that days.
Inside this library was tool (ASNparser) which converted ASN.1 definitions into container classes. Also there was framework which allowed serialization / de-serialization of these containers using higher layer abstractions. Note they are auto-generated. They supported several encoding protocols (BER,PER,XER) for ASN.1 with very complex ASN sntax and good-enough performance.
What was nice?
Auto-generated container classes which were suitable enough for clear logic implementation.
I managed to rework whole container layer under ASN objects hierarchy without almost any modification for upper layers.
It was relatively easy to do refactoring (performance) for debug features of that ASN classes (I understand, authors didn't intended to expect 20xE1 calls signalling to be logged online).
What was not suitable?
Non-STL library with lazy copy under this. Refactored by speed but I'd like to have STL compatibility there (at least that time).
You can find Wiki page of all the project here. You should focus only on PTlib component, ASN parser sources, ASN classes hierarchy / encoding / decoding policies hierarchy.
By the way,look around "Bridge" design pattern, it might be useful.
Feel free to comment questions if something seen to be strange / not enough / not that you requested actuall.

How would you implement Erlang-like send and receive in C++?

Actually, this question seems to have two parts:
How to implement pattern matching?
How to implement send and receive (i.e. the Actor model)?
For the pattern matching part, I've been looking into various projects like App and Prop. These look pretty nice, but couldn't get them to work on a recent version (4.x) of g++. The Felix language also seems to support pattern matching pretty well, but isn't really C++.
As for the Actor model, there are existing implementations like ACT++ and Theron, but I couldn't find anything but papers on the former, and the latter is single-threaded only [see answers].
Personally, I've implemented actors using threading and a thread-safe message queue. Messages are hash-like structures, and used these together with a number of preprocessor macros to implemented simple pattern matching.
Right now, I can use the following code to send a message:
(new Message(this))
->set("foo", "bar")
->set("baz", 123)
->send(recipient);
And the following to do simple pattern matching (qDebug and qPrintable are Qt-specific):
receive_and_match(m)
match_key("foo") { qDebug("foo: %s", qPrintable(m->value("foo").toString())); }
or_match_key("baz") { qDebug("baz: %d", m->value("baz").toInt()); }
or_match_ignore
end_receive
However, this looks a bit hackish to me, and isn't very robust.
How would you do it? Did I miss any existing work?
As for the Actor model, there are
existing implementations like ACT++
and Theron, but I couldn't find
anything but papers on the former, and
the latter is single-threaded only.
As the author of Theron, I was curious why you believe it's single-threaded?
Personally, I've implemented actors
using threading and a thread-safe
message queue
That's how Theron is implemented.. :-)
Ash
One of the important things about erlang is how the features are used to make robust systems.
The send/recieve model is no-sharing, and explicitly copying.
The processes themselves are lightweight threads.
If you did desire the robust properties of the erlang model, you would be best to use real processes and IPC rather than threads.
If you want robust message passing though you may end up wanting to serialize and deserialise the contents. Especially with type safety.
Pattern matching in C++ isn't always pretty but there will be a good pattern for this - you will end up creating a dispatcher object that uses some form of polymorphism to get what you want.
Although if you are not careful you end up with xml over pipes :)
Really, if you want the erlang model you really want to use erlang. If there are slow bits, I'm sure you can augment your program using a foreign function internet.
The problem about re-implementing parts, is you won't get a good cohesive library and solution. The solutions you have already don't look much like C++ anymore.
I'm currently implementing an actor library for C++ called "acedia" (there's nothing yet about it on google) that uses "type matching". The library is a project for my master thesis and you can send any kind of data to an actor with it.
A small snippet:
recipient.send(23, 12.23f);
And on the recipient side you can either analyze the received message like this:
Message msg = receive();
if (msg.match<int, float>() { ... }
... or you can define a rule set that invokes a function or method for you:
void doSomething(int, float);
InvokeRuleSet irs;
irs.add(on<int, float>() >> doSomething);
receiveAndInvoke(irs);
It's also possible to match both on type and on value:
Message msg = receive();
if (msg.match<int, float>(42, WILDCARD) { ... }
else if (msg.match<int, float>() { ... }
The constant "WILDCARD" means, that any value will be acceptet. Pass no arguments is equal set all arguments to "WILDCARD"; meaning that you only want to match the types.
This is certainly a small snippet. Also you can use "case classes" like in Scala. They are comparable to "atomics" in erlang. Here is a more detailed example:
ACEDIA_DECLARE_CASE_CLASS(ShutdownMessage)
ACEDIA_DECLARE_CASE_CLASS(Event1)
ACEDIA_DECLARE_CASE_CLASS(Event2)
To react to the defined case classes you can write an actor like this:
class SomeActor : public Actor
{
void shutdown() { done = true; }
void handleEvent1();
void handleEvent1();
public:
SomeActor() : done(false) { }
virtual void act()
{
InvokeRuleSet irs;
irs
.add(on<ShutdownMessage>() >> method(&SomeActor::shutdown))
.add(on<Event1>() >> method(&SomeActor::handleEvent1))
.add(on<Event2>() >> method(&SomeActor::handleEvent2))
;
while (!done) receiveAndInvoke(irs);
}
};
To create a new actor and start it, all you have to write is:
Acedia::spawn<SomeActor>();
Although the library not even reached beta stadium the shown snippets work and i have a first application running on it. One major goal of the library is to support distributed programming (also across a network).
Your question is a while ago, but if you're interested in it: let me know! :)
You can mimic the behavior using Qt's signal/slot mechanism, especially since Qt's signal/slot supports multithread.
I would definitely be interested in looking at your "acedia" library and would love to help in any way that I could. Erlang has some wonderful constructs and C++ could definitely benefit from such a library.
Today I hostet the library at sourceforge: https://sourceforge.net/projects/acedia/
As I said before it's an early release. But feel free to critique it!
Today, if you want erlang style robust actors in C++, and pattern matching,
maybe Rust is the answer.
Of course this wasn't around publically when the OP asked ~5years ago, and as of april 2014 it still isn't v1.0 yet - but its been progressing very well and is definitely stabilizing, enough of the language core is stable I think.
And ok its not C++, but it has the same approach to memory management as C++, except that it supports lightweight tasks with no shared memory by default (then provides controlled library features for sharing - "Arc");
It can directly call (and directly expose) 'extern C' functions. You can't share templated library headers with C++ - but you can write generics that mimick C++ collection classes (and vica versa) to pass references to data-structures across.