<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Eugene,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Another way to look at the workflow is to make sure that the LBaaS Plugin updates the database synchronously (and generates the resource ID before returning to the user), and then let it to the driver implementations to decide whether they want to handle the call synchronously or asynchronously.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>I like drawing pictures to avoid misunderstandings, so here are 2 pictures illustrating 2 vendors, one deciding to implement their driver in a synchronous way, and the other one in an asynchronous way. <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Synchronous driver implementation: </span><a href="http://wiki.openstack.org/Quantum/LBaaS?action=AttachFile&do=view&target=LBaaS+synchronous+driver+implementation.png">http://wiki.openstack.org/Quantum/LBaaS?action=AttachFile&do=view&target=LBaaS+synchronous+driver+implementation.png</a><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Asynchronous driver implementation: </span><a href="http://wiki.openstack.org/Quantum/LBaaS?action=AttachFile&do=view&target=LBaaS+asynchronous+driver+implementation.png">http://wiki.openstack.org/Quantum/LBaaS?action=AttachFile&do=view&target=LBaaS+asynchronous+driver+implementation.png</a><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>As far as the plugin is concerned, the calls to drivers are always synchronous in the sense that the driver doesn’t have to deal with queues, etc. The plugin should expect the driver to return either a “COMPLETED” status (meaning the call has been executed on the device), ora “PENDING” status (meaning that the driver has started the operation but it is not complete). The plugin updates the database in both cases with the outcome of the call, and returns the result to the user. <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>This would allow a lot of freedom in driver implementations. A vendor can start with a synchronous implementation because it is quick to implement, and then later on move on to an asynchronous implementation without impacting the LBaaS plugin. Or it can implement some calls synchronously while other calls (which might take a long time to complete) asynchronously. You can also have different vendors using different driver strategies wrt. Synchronicity, or using different queuing mechanisms.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Thanks<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Youcef<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><a name="_MailEndCompose"><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></a></p><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Eugene Nikanorov [mailto:enikanorov@mirantis.com] <br><b>Sent:</b> Monday, November 12, 2012 6:24 AM<br><b>To:</b> openstack-dev@lists.openstack.org<br><b>Subject:</b> [openstack-dev] [Quantum][LBaaS] Architecture: Agents, Drivers, async calls<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Hi folks,<o:p></o:p></p><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>In the latest meeting we've mentioned several important architectural points including:<o:p></o:p></p></div><div><p class=MsoNormal>- agents vs direct driver call<o:p></o:p></p></div><div><p class=MsoNormal>- asynchronous execution<o:p></o:p></p></div><div><p class=MsoNormal>- dispatching a generic REST call to a proper driver.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>I would like to present how Mirantis team sees this based on our previous experience with LBaaS and other openstack components.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>We need asynchronous execution in the sense that client gets immediate response while actual device configuration happens later.<o:p></o:p></p></div><div><p class=MsoNormal>Workflow of such operation could look like following:<o:p></o:p></p></div><div><p class=MsoNormal>1) client makes REST call; receives an object it has created/modified with PENDING status <o:p></o:p></p></div><div><p class=MsoNormal>2) call is dispatched to a plugin, plugin creates/modifies/etc an object in the database<o:p></o:p></p></div><div><p class=MsoNormal>3) plugin calls driver to apply new configuration to specific device<o:p></o:p></p></div><div><p class=MsoNormal>4) driver finishes applying configuration, plugin updates DB object<o:p></o:p></p></div><div><p class=MsoNormal>5) client polls objectID and gets final status of operation.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Now depending on approach we take, (3) could expand into different sequence of operations.<o:p></o:p></p></div><div><p class=MsoNormal>One of the good options to choose could be using agent between plugin and drivers. In this case (3) expands to:<o:p></o:p></p></div><div><p class=MsoNormal>3.1 plugin posts message to mq<o:p></o:p></p></div><div><p class=MsoNormal>3.2. message is consumed by one of the running service agents<o:p></o:p></p></div><div><p class=MsoNormal>3.3. agent calls corresponding driver directly in synchronous way.<o:p></o:p></p></div><div><p class=MsoNormal>3.4. agent posts message upon completion.<o:p></o:p></p></div><div><p class=MsoNormal>3.5. plugin consumes the message and updates DB object with final status<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Such approach solves at least two potential problems:<o:p></o:p></p></div><div><p class=MsoNormal>1. plugin may be simplified since it is not required to implement call/work item queuing <o:p></o:p></p></div><div><p class=MsoNormal>2. Applying device configuration is time consuming task which could take seconds. <o:p></o:p></p></div><div><p class=MsoNormal>Both plugin and agent has thread limit for any concurrent operations. <o:p></o:p></p></div><div><p class=MsoNormal>Handling heavy workload in large deployments will be simple with several agents consuming messages from mq.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Also this allows to create synchronous drivers since asyncness will be handled by mq + agent.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Another option could be calling drivers directly without any asyncness at all while preserving above workflow (1-5). <o:p></o:p></p></div><div><p class=MsoNormal>That could work as temporary fast solution while allowing to split it to "plugin + agent approach" relatively easily.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Regarding the dispatching REST calls to proper driver:<o:p></o:p></p></div><div><p class=MsoNormal>In fact, VIP object should contain reference to particular device it is created at. <o:p></o:p></p></div><div><p class=MsoNormal><a href="http://wiki.openstack.org/LBaaS/CoreResourceModel/proposal" target="_blank">http://wiki.openstack.org/LBaaS/CoreResourceModel/proposal</a> misses that device management part, I think it was just implied there.<o:p></o:p></p></div><div><p class=MsoNormal>Every balancer-related object references the VIP and hence references the specific device where it was created. <o:p></o:p></p></div><div><p class=MsoNormal>E,g, when a call for any object is made, plugin needs to extract device type from DB following those references and later plugin or agent will use it to call particular driver.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Thanks,<o:p></o:p></p></div><div><p class=MsoNormal>Eugene.<o:p></o:p></p></div></div></body></html>