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/09/17 16:30:06 UTC

[jira] [Updated] (MESOS-3455) Higher level construct for expressing process dispatch

     [ https://issues.apache.org/jira/browse/MESOS-3455?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jojy Varghese updated MESOS-3455:
---------------------------------
    Description: 
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.

  was:
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.


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