You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@mesos.apache.org by "Jojy Varghese (JIRA)" <ji...@apache.org> on 2015/12/15 01:52:46 UTC
[jira] [Commented] (MESOS-3455) Higher level construct for
expressing process dispatch
[ 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)