From c38148f3661fe5fb6fee7eeec202b5739ef87db8 Mon Sep 17 00:00:00 2001
From: Bensong Liu <bensl@microsoft.com>
Date: Thu, 22 Oct 2020 17:25:29 +0800
Subject: [PATCH] fix a bug: reducing bug on    A OP (B OP C): Right side queue
 not merged in.

---
 activity.hpp                    | 21 +++++++++++++++------
 workflows/E2EPOC-BuildPortal.cc |  2 +-
 workflows/another.cc            | 25 +++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 7 deletions(-)
 create mode 100644 workflows/another.cc

diff --git a/activity.hpp b/activity.hpp
index 0000ae5..fa089bd 100644
--- a/activity.hpp
+++ b/activity.hpp
@@ -111,7 +111,7 @@ namespace CIS {
             xamlCode = activity.generateXaml();
         }
         explicit Flow(rlib::string xamlCode) : xamlCode(xamlCode) {}
-        Flow(const Flow &another) : queued(another.queued), xamlCode(another.xamlCode), prevOperationIsSequential(another.prevOperationIsSequential) {}
+        Flow(const Flow &another) : queuedOnRight(another.queuedOnRight), xamlCode(another.xamlCode), prevOperationIsSequential(another.prevOperationIsSequential) {}
 
         // Actually modify xamlCode on "OperationChange". 
         // for example, A >> B >> C >> D | E. ABCD should be merged into one sequential operation. 
@@ -129,7 +129,9 @@ namespace CIS {
     private:
         bool prevOperationIsSequential = true;
         rlib::string xamlCode;
-        std::queue<rlib::string> queued;
+
+        // For a long expression A >> B >> C >> D, A is in xamlCode, and [B,C,D] are cached in queuedOnRight to wait for merge. 
+        std::list<rlib::string> queuedOnRight;
 
         Flow binaryOperation(Flow seqNext, bool thisOperationIsSequential) const {
             Flow result = *this;
@@ -137,18 +139,25 @@ namespace CIS {
             seqNext.reduceQueuedIfNecessary(thisOperationIsSequential);
 
             result.prevOperationIsSequential = thisOperationIsSequential;
-            result.queued.push(seqNext.xamlCode);
+
+            result.queuedOnRight.emplace_back(seqNext.xamlCode);
+            for(auto &&item : seqNext.queuedOnRight)
+                result.queuedOnRight.emplace_back(item);
             return result;
         }
 
         void reduceQueuedIfNecessary(bool thisOperationIsSequential) {
-            if(thisOperationIsSequential == prevOperationIsSequential || queued.empty()) return;
+            if(thisOperationIsSequential == prevOperationIsSequential || queuedOnRight.empty()) return;
             rlib::string resultXaml = prevOperationIsSequential ? templates::SEQ_BEGIN : templates::PAR_BEGIN;
+
             resultXaml += xamlCode;
-            while(!queued.empty())
-                resultXaml += queued.front(), queued.pop();
+            for(auto &&item : queuedOnRight)
+                resultXaml += item;
+
             resultXaml += prevOperationIsSequential ? templates::SEQ_END : templates::PAR_END;
+
             xamlCode = std::move(resultXaml);
+            queuedOnRight.clear();
         }
     };
 
diff --git a/workflows/E2EPOC-BuildPortal.cc b/workflows/E2EPOC-BuildPortal.cc
index 6797d0b..23759e3 100644
--- a/workflows/E2EPOC-BuildPortal.cc
+++ b/workflows/E2EPOC-BuildPortal.cc
@@ -12,5 +12,5 @@ int main() {
     DEFINE_ACTIVITY(CustomerLockboxUX);
 
     auto flow = AdminCenterApp | OfficeHome | ShellServices | PortalUseageReports | SvcHealthDashboard | CustomerLockboxUX;
-    println(to_file("BuildPortal.xaml"), flow.generateXaml("FleetAGC.Workflows.BuildPortal"));
+    println(to_file("E2EPOCBuildPortalWorkflow.xaml"), flow.generateXaml("FleetAGC.Workflows.BuildPortal"));
 }
diff --git a/workflows/another.cc b/workflows/another.cc
new file mode 100644
index 0000000..87f88ee
--- /dev/null
+++ b/workflows/another.cc
@@ -0,0 +1,25 @@
+#include <cis-workflow-gen/quick-include.hpp>
+
+int main() {
+    #define DEFINE_ACTIVITY(name, entityName) \
+        Activity name (#name, "FleetAGC.Activities.DelayActivity", entityName); \
+        name.addInputSetting("Timespan", "60");
+    
+    DEFINE_ACTIVITY(GridManager, "M365Poc.SPO.GridManager")
+    DEFINE_ACTIVITY(AuthAndProvision, "M365Poc.SPO.AuthProvisioning")
+    DEFINE_ACTIVITY(FarmsAndTennats, "")
+    DEFINE_ACTIVITY(CSC , "")
+    DEFINE_ACTIVITY(FastSearch , "")
+    DEFINE_ACTIVITY(Microservices, "M365Poc.SPO.MicroServices")
+    DEFINE_ACTIVITY(MonitorAndAlert, "M365Poc.SPO.MonitoringAlerting")
+    DEFINE_ACTIVITY(SPOTooling, "M365Poc.SPO.SPOTooling")
+    DEFINE_ACTIVITY(UXCDNFailover, "M365Poc.SPO.UXCDNFailover")
+    DEFINE_ACTIVITY(ODFBSyncClient, "M365Poc.SPO.ODFBSyncClient")
+ 
+    auto block1 = GridManager >> FarmsAndTennats >> (CSC | FastSearch);
+    auto block2 = Microservices | MonitorAndAlert;
+    auto completeFlow = block1 | AuthAndProvision | block2;// | SPOTooling | UXCDNFailover | ODFBSyncClient;
+ 
+    println(to_file("SPOBuildoutPOCWorkflow.xaml"), completeFlow.generateXaml("FleetAGC.Workflows.SPOBuildoutPOCWorkflow"));
+}
+
-- 
GitLab