Jojy Varghese created MESOS-3455: ------------------------------------ Summary: Higher level construct for expressing process dispatch Key: MESOS-3455 URL: https://issues.apache.org/jira/browse/MESOS-3455 Project: Mesos Issue Type: Bug Components: libprocess Reporter: Jojy Varghese Assignee: Jojy Varghese
Since mesos code is based on the actor model and dispatching an interface asynchronously is a large part of the code base, generalizing the concept of asynchronously dispatching an interface would eliminate the need to manual programming of the dispatch boilerplate. An example usage: For a simple interface like: class Interface { virtual Future<size_t> writeToFile(const char* data) = 0; virtual ~Interface(); }; Today the developer has to do the following: a. Write a wrapper class that implements the same interface to add the dispatching boilerplate. b. Spend precious time in reviews. c. Risk introducing bugs. None of the above steps add any value to the executable binary. The wrapper class would look like: // -- hpp file class InterfaceProcess; class InterfaceImpl : public Interface { public: Try<Owned<InterfaceImpl>> create(const Flags& flags); virtual Future<size_t> writeToFile(const char* data); ~InterfaceImpl(); private: Owned<InterfaceProcess> process; }; // -- cpp file Try<Owned<InterfaceImpl>> create(const Flags& flags) { // Code to create the InterfaceProcess class. } Future Future<size_t> InterfaceImpl::writeToFile(const char* data) { process->dispatch( &InterfaceProcess::writeToFile, data); } InterfaceImpl::InterfaceImpl() { // Code to spawn the process } InterfaceImpl::~InterfaceImpl() { // Code to stop the process. } At the caller/client site, the code would look like: Try<Owned<Interface>> in = InterfaceImpl::create(flags); Future<size_t> result = in->writeToFile(data); Proposal We should use C++'s rich language semnatics to express the intent and avoid the boilerplate we write manually. The basic intent of the code that leads to all the boilerplate above is: a. An interface that provides a set of functionality. b. An implementation of the interface. c. Ability to dispatch that interface asynchronously using actor. C++ has a rich set of generics that can be used to express above. Components ProcessDispatcher This component will "dispatch" an interface implementation asychronously using the process framework. This component can be expressed as: ProcessDispatcher<Interface, InterfaceImplmentation> DispatchInterface Any interface that provides an implementation that can be "dispatched" can be expressed using this component. This component can be expressed as: Dispatchable<Interface> Usage: Simple usage Try<Owned<Dispatchable<Interface>>> dispatcher = ProcessDispatcher<Interface, InterfaceImpl>::create(flags); Future<size_t> result = dispatcher->dispatch( Interface::writeToFile, data); Collecting the interface in a container vector<Owned<Dispatchable<Interface>>> dispatchCollection; Try<Owned<Dispatchable<Interface>>> dispatcher1 = ProcessDispatcher<Interface, InterfaceImpl1>::create(flags); Try<Owned<Dispatchable<Interface>>> dispatcher2 = ProcessDispatcher<Interface, InterfaceImpl2>::create("test"); dispatchCollection.push_back(dispatcher1); dispatchCollection.push_back(dispatcher2); The advantages of using the generic dispatcher: Saves time by avoiding to write all the boilerplate and going through review cycles. Less bugs. Focus on real problem and not boilerplate. Less code in the text segment. -- This message was sent by Atlassian JIRA (v6.3.4#6332)