[ 
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)

Reply via email to