Search code examples
c++c++11lambdaactormessage

Message receive for c++ actor system


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:

  1. 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.

  2. 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.


Solution

  • 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. ;)