lundi 24 octobre 2016

Efficient message factory and handler in C++

Our company is rewriting most of the legacy C code in C++11. (Which also means I am a C programmer learning C++). I need advice on message handlers.

We have distributed system - Server process sends a packed message over TCP to client process.

In C code this was being done: - parse message based on type and subtype, which are always the first 2 fields

- call a handler as handler[type](Message *msg)

- handler creates temporary struct say, tmp_struct to hold the parsed values and .. 

- calls subhandler[type][subtype](tmp_struct)

There is only one handler per type/subtype.

Moving to C++11 and mutli-threaded environment. The basic idea I had was to -

1) Register a processor object for each type/subtype combination. This is
actually a vector of vectors - vector< vector >

class MsgProcessor {

    // Factory function
    virtual Message *create();
    virtual Handler(Message *msg)
}

This will be inherited by different message processors

class AMsgProcessor : public MsgProcessor {

      Message *create() override();
      handler(Message *msg);
}

2) Get the processor using a lookup into the vector of vectors. Get the message using the overloaded create() factory function. So that we can keep the actual message and the parsed values inside the message.

3) Now a bit of hack, This message should be send to other threads for the heavy processing. To avoid having to lookup in the vector again, added a pointer to proc inside the message.

class Message {
    const MsgProcessor *proc; // set to processor, 
                              // which we got from the first lookup
                              // to get factory function.
};

So other threads, will just do

Message->proc->Handler(Message *);

This looks bad, but hope, is that this will help to separate message handler from the factory. This is for the case, when multiple type/subtype wants to create same Message, but handle it differently.

I was searching about this and came across :

http://ift.tt/2eM88jv

It provides a way to completely separate the message from the handler. But I was wondering if my simple scheme above will be considered an acceptable design or not. Also is this a wrong way of achieving what I want?

Efficiency, as in speed, is the most important requirement from this application. Already we are doing couple of memory Jumbs => 2 vectors + virtual function call the create the message. There are 2 deference to get to the handler, which is not good from caching point of view I guess.

Aucun commentaire:

Enregistrer un commentaire