[
https://issues.apache.org/jira/browse/MESOS-3455?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15057090#comment-15057090
]
Jojy Varghese commented on MESOS-3455:
--------------------------------------
Added patches for review/discussions:
https://github.com/conqer/mesos/commit/4cb034edb115870ea69fbd5c2c5891e0b038f01d
https://github.com/conqer/mesos/commit/f611143e40064c056039015431e62a3698395131
https://github.com/conqer/mesos/commit/1695c98f20b580bf0654f06b80befae1d8caaf88
> 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:
> {code}
> class Interface
>
> {
>
> virtual Future<size_t> writeToFile(const char* data) = 0;
>
> virtual ~Interface();
>
> };
> {code}
> 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:
> {code}
> // -- 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.
>
> }
> {code}
> At the caller/client site, the code would look like:
> {code}
> Try<Owned<Interface>> in = InterfaceImpl::create(flags);
>
> Future<size_t> result =
>
> in->writeToFile(data);
> {code}
>
> 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:
> {code}
> ProcessDispatcher<Interface, InterfaceImplmentation>
> {code}
> DispatchInterface
> Any interface that provides an implementation that can be "dispatched" can be
> expressed using this component.
> This component can be expressed as:
> {code}
> Dispatchable<Interface>
> {code}
> Usage:
> Simple usage
> {code}
> Try<Owned<Dispatchable<Interface>>> dispatcher =
>
> ProcessDispatcher<Interface, InterfaceImpl>::create(flags);
>
> Future<size_t> result =
>
> dispatcher->dispatch(
>
> Interface::writeToFile,
>
> data);
> {code}
>
> Collecting the interface in a container
> {code}
> 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);
> {code}
> 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.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)