IFL-CAMP / simple

S.I.M.P.L.E. - Smart Intuitive Messaging Platform with Less Effort. A Cross-Platform C++ Library to Exchange Data Across Network.
Mozilla Public License 2.0
22 stars 5 forks source link

asymmetric request-reply #46

Open joebedard opened 6 years ago

joebedard commented 6 years ago

It looks like request-reply is currently symmetric. In other words, the entire object is sent to the server, which processes the object, and then the entire object is sent back to the client. I have a scenario where the request object is large, and the reply is only a boolean. My application is performance-critical, so I want to minimize the data which is returned to the client. It would be helpful if simple could support an asymmetric request-reply like this:

bool server_callback(simple_msgs::HugeObject & ho)
{
   bool status = true;
   //process the ho, and set status accordingly
   return status;
}

int main(int argc, char * argv[]) try
{
   simple::Server<simple_msgs::HugeObject, bool> server{ "tcp://*:5000", server_callback };
   std::cout << "Press a key to exit.\n";
   std::cin.get();
   return 0;
}
SalvoVirga commented 6 years ago

Hum, stupid question: can't you just reply with a message that contains the proper answer as a boolean and keep the rest of the message empty? So if you send a message that is composed of an Image + Bool as request, you process the image and set the boolean value according to the outcome of your process and the image part as just an empty image.

joebedard commented 6 years ago

That's a good question :) and I'm not sure. simple is based on FlatBuffers so, I guess we'd define a simple_msgs::MyServiceParameters class that is a union of HugeObject and bool. This seems to be more of a work-around, and in my opinion, it's not as elegant as above.

SalvoVirga commented 6 years ago

On the server side the benefit is clear, but on the client side this will introduce more complexity when dealing with failure cases.

For example, a simple::Client<my_msgs::MyServiceParameters> my_client(...) right now would send requests to a server like this: bool success = my_client.request(my_message);

my_message will contain the server reply only if the reply was correctly received and the returned boolean makes it very easy to handle failure cases.

If we change to something like simple::Client<RequestType, ReplyType> my_client(...), the signature for the request method would change into ReplyType request(RequestType& request). The question is then how to handle failures, should a user handle an exception? 😕

joebedard commented 6 years ago

Yes, the user should handle exceptions. :-) I've been using cppzmq (which throws exceptions) and it works very well. You could do something similar to error_t in cppzmq.

Alternatively, you could do this: bool request(RequestType & request, ReplyType & reply).