You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@heron.apache.org by th...@apache.org on 2022/05/15 07:40:07 UTC

[incubator-heron] branch feature/add-instances-of-ui created (now 272ad2059a0)

This is an automated email from the ASF dual-hosted git repository.

thinker0 pushed a change to branch feature/add-instances-of-ui
in repository https://gitbox.apache.org/repos/asf/incubator-heron.git


      at 272ad2059a0 Added to show the number of instances in the topology list UI.

This branch includes the following new commits:

     new 272ad2059a0 Added to show the number of instances in the topology list UI.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-heron] 01/01: Added to show the number of instances in the topology list UI.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thinker0 pushed a commit to branch feature/add-instances-of-ui
in repository https://gitbox.apache.org/repos/asf/incubator-heron.git

commit 272ad2059a0a0e12e3b6cc254500b6feea793816
Author: choi se <th...@gmail.com>
AuthorDate: Fri May 13 15:36:12 2022 +0900

    Added to show the number of instances in the topology list UI.
    
    Add TestCase test_instances of Tracker
    
    Change number type of Instances
    
    Change number type of Instances
    
    Check has attribute of physical_play
---
 heron/tools/tracker/src/python/topology.py         | 10 ++++---
 heron/tools/tracker/tests/python/mock_proto.py     | 31 +++++++++++++++++++++-
 .../tracker/tests/python/topology_unittest.py      | 17 ++++++++++++
 .../tools/ui/resources/static/js/alltopologies.js  | 26 +++++++++++-------
 heron/tools/ui/resources/templates/topology.html   |  2 ++
 5 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/heron/tools/tracker/src/python/topology.py b/heron/tools/tracker/src/python/topology.py
index 89a6ac6409c..817c35073d2 100644
--- a/heron/tools/tracker/src/python/topology.py
+++ b/heron/tools/tracker/src/python/topology.py
@@ -52,6 +52,7 @@ class TopologyInfoMetadata(BaseModel):
   release_username: str
   release_tag: str
   release_version: str
+  instances: int = 0
   extra_links: List[Dict[str, str]]
 
 class TopologyInfoExecutionState(TopologyInfoMetadata):
@@ -274,7 +275,7 @@ class Topology:
     return TopologyInfo(
         id=topology.id,
         logical_plan=self._build_logical_plan(topology, execution_state, physical_plan),
-        metadata=self._build_metadata(topology, execution_state, tracker_config),
+        metadata=self._build_metadata(topology, physical_plan, execution_state, tracker_config),
         name=topology.name, # was self.name
         packing_plan=self._build_packing_plan(packing_plan),
         physical_plan=self._build_physical_plan(physical_plan),
@@ -313,7 +314,7 @@ class Topology:
         topology_pb2.PAUSED: "Paused",
         topology_pb2.KILLED: "Killed",
     }.get(physical_plan.topology.state if physical_plan else None, "Unknown")
-    metadata = Topology._build_metadata(topology, execution_state, tracker_config)
+    metadata = Topology._build_metadata(topology, physical_plan, execution_state, tracker_config)
     return TopologyInfoExecutionState(
         has_physical_plan=bool(physical_plan),
         has_packing_plan=bool(packing_plan),
@@ -378,7 +379,8 @@ class Topology:
     return info
 
   @staticmethod
-  def _build_metadata(topology, execution_state, tracker_config) -> TopologyInfoMetadata:
+  def _build_metadata(topology, physical_plan, execution_state, tracker_config) \
+          -> TopologyInfoMetadata:
     if not execution_state:
       return  TopologyInfoMetadata()
     metadata = {
@@ -392,6 +394,8 @@ class Topology:
         "release_tag": execution_state.release_state.release_tag,
         "release_version": execution_state.release_state.release_version,
     }
+    if physical_plan is not None and hasattr(physical_plan, "instances"):
+      metadata["instances"] = len(physical_plan.instances)
     extra_links = deepcopy(tracker_config.extra_links)
     Topology._render_extra_links(extra_links, topology, execution_state)
     return TopologyInfoMetadata(
diff --git a/heron/tools/tracker/tests/python/mock_proto.py b/heron/tools/tracker/tests/python/mock_proto.py
index f939395d0e9..ebe4491a52f 100644
--- a/heron/tools/tracker/tests/python/mock_proto.py
+++ b/heron/tools/tracker/tests/python/mock_proto.py
@@ -176,14 +176,43 @@ class MockProto:
 
     return topology
 
+  def create_mock_stream_manager(self):
+    stmgr = protoPPlan.StMgr()
+    stmgr.id = "mock_stream1"
+    stmgr.host_name = "local"
+    stmgr.local_endpoint = ":1000"
+    stmgr.local_data_port = 1001
+    stmgr.shell_port = 1002
+    stmgr.data_port = 1003
+    stmgr.cwd = ""
+    stmgr.pid = 1
+    return stmgr
+
+  def create_mock_instance(self, i):
+    instance = protoPPlan.Instance()
+    instance.instance_id = f"mock_instance{i}"
+    instance.stmgr_id = f"mock_stream{i}"
+    instance_info = protoPPlan.InstanceInfo()
+    instance_info.task_id = i
+    instance_info.component_index = i
+    instance_info.component_name = f"mock_spout"
+    instance.info.CopyFrom(instance_info)
+    return instance
+
   def create_mock_simple_physical_plan(
       self,
       spout_parallelism=1,
-      bolt_parallelism=1):
+      bolt_parallelism=1,
+      instances_num=1):
     pplan = protoPPlan.PhysicalPlan()
     pplan.topology.CopyFrom(self.create_mock_simple_topology(
         spout_parallelism,
         bolt_parallelism))
+    pplan.stmgrs.extend([self.create_mock_stream_manager()])
+    instances = []
+    for i in range(instances_num):
+      instances.append(self.create_mock_instance(i+1))
+    pplan.instances.extend(instances)
     return pplan
 
   def create_mock_simple_packing_plan(
diff --git a/heron/tools/tracker/tests/python/topology_unittest.py b/heron/tools/tracker/tests/python/topology_unittest.py
index a03ea4aeb36..f48a17fd8e2 100644
--- a/heron/tools/tracker/tests/python/topology_unittest.py
+++ b/heron/tools/tracker/tests/python/topology_unittest.py
@@ -116,3 +116,20 @@ def test_bolts(topology):
   assert 3 == len(bolts)
   assert ["mock_bolt1", "mock_bolt2", "mock_bolt3"] == \
                    topology.bolt_names()
+
+
+def test_containers(topology):
+  # Set pplan now
+  pplan = MockProto().create_mock_simple_physical_plan()
+  topology.set_physical_plan(pplan)
+
+  assert 1 == len(pplan.instances)
+
+  estate = MockProto().create_mock_execution_state()
+  topology.set_execution_state(estate)
+
+  tracker = MagicMock(Tracker)
+  tracker.config.extra_links = []
+
+  top_info_meta = topology._build_metadata(topology, pplan, estate, tracker.config)
+  assert 1 == top_info_meta.instances
diff --git a/heron/tools/ui/resources/static/js/alltopologies.js b/heron/tools/ui/resources/static/js/alltopologies.js
index a45534a5fe5..e9140c77773 100644
--- a/heron/tools/ui/resources/static/js/alltopologies.js
+++ b/heron/tools/ui/resources/static/js/alltopologies.js
@@ -30,8 +30,9 @@ var TopologyItem = React.createClass({
     };
 
     var topology = this.props.topology;
-    var displaycluster = topology.cluster.toUpperCase();
-    var displayenv = topology.environ.toUpperCase();
+    var display_cluster = topology.cluster.toUpperCase();
+    var display_env = topology.environ.toUpperCase();
+    var display_instances = topology.instances;
     var display_time = "-";
     if (topology.submission_time !== "-") {
       display_time = moment(topology.submission_time * 1000).fromNow();
@@ -53,14 +54,15 @@ var TopologyItem = React.createClass({
     return (
        <tr className={state_class}>
          <td className="col-md-1 index no-break">{index}</td>
-         <td className="col-md-3 break-all"><a className="toponame" href={'./topologies/' + topology.cluster + '/' + topology.environ + '/' + topology.name}>{topology.name}</a></td>
-         <td className="col-md-1 topostatus">{topology.status}</td>
-         <td className="col-md-1 topocluster">{displaycluster}</td>
-         <td className="col-md-1 toporunrole break-all">{topology.role}</td>
-         <td className="col-md-1 topoenviron">{displayenv}</td>
-         <td className="col-md-2 toporeleaseversion break-all">{topology.release_version}</td>
-         <td className="col-md-1 toposubmittedby break-all">{topology.submission_user}</td>
-         <td className="col-md-2 toposubmittedat no-break">{display_time}</td>
+         <td className="col-md-3 break-all"><a className="topo_name" href={'./topologies/' + topology.cluster + '/' + topology.environ + '/' + topology.name}>{topology.name}</a></td>
+         <td className="col-md-1 topo_status">{topology.status}</td>
+         <td className="col-md-1 topo_cluster">{display_cluster}</td>
+         <td className="col-md-1 topo_runrole break-all">{topology.role}</td>
+         <td className="col-md-1 topo_environ">{display_env}</td>
+         <td className="col-md-1 topo_instances">{display_instances}</td>
+         <td className="col-md-2 topo_releaseversion break-all">{topology.release_version}</td>
+         <td className="col-md-1 topo_submittedby break-all">{topology.submission_user}</td>
+         <td className="col-md-2 topo_submittedat no-break">{display_time}</td>
        </tr>
     );
   }
@@ -94,6 +96,7 @@ var TopologyTable = React.createClass({
                 role: estate.role,
                 has_physical_plan: estate.has_physical_plan,
                 has_tmanager_location: estate.has_tmanager_location,
+                instances: estate.instances,
                 release_version: estate.release_version,
                 submission_time: estate.submission_time,
                 submission_user: estate.submission_user,
@@ -193,6 +196,9 @@ var TopologyTable = React.createClass({
               <th onClick={sortBy("environ")} className={sortClass("environ")}>
                 Environ
               </th>
+              <th onClick={sortBy("instances")} className={sortClass("instances")}>
+                Instances
+              </th>
               <th onClick={sortBy("release_version")} className={sortClass("release_version")}>
                 Version
               </th>
diff --git a/heron/tools/ui/resources/templates/topology.html b/heron/tools/ui/resources/templates/topology.html
index 38f55c753c4..692f05fe04f 100644
--- a/heron/tools/ui/resources/templates/topology.html
+++ b/heron/tools/ui/resources/templates/topology.html
@@ -58,6 +58,7 @@ under the License.
       <th>Cluster</th>
       <th>Role</th>
       <th>Environment</th>
+      <th>Instances</th>
       <th>Version</th>
       <th>Launched at</th>
       <th>Submitted by</th>
@@ -71,6 +72,7 @@ under the License.
         <td>{{cluster}}</td>
         <td>{{execution_state['role']}}</td>
         <td>{{environ}}</td>
+        <td>{{instances}}</td>
         <td>{{execution_state['release_version']}}</td>
         <td>{{launched}}</td>
         <td>{{execution_state['submission_user']}}</td>