Add parallelism calculator in Heron UI (#3401)
diff --git a/heron/tools/ui/resources/static/css/main.css b/heron/tools/ui/resources/static/css/main.css
index 0ae4425..f13666d 100644
--- a/heron/tools/ui/resources/static/css/main.css
+++ b/heron/tools/ui/resources/static/css/main.css
@@ -2291,4 +2291,10 @@
div#topologydetails.display-counters div.display-info.display-counters,
div#topologydetails.display-config div.display-info.display-config {
display: block;
-}
\ No newline at end of file
+}
+
+/* Backdrop in bootstrap 3 seems to have solid color and we would like it to be half transparent */
+div.modal-backdrop.fade.in {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
diff --git a/heron/tools/ui/resources/static/js/topologies.js b/heron/tools/ui/resources/static/js/topologies.js
index 764e0aa..ff8dbbe 100644
--- a/heron/tools/ui/resources/static/js/topologies.js
+++ b/heron/tools/ui/resources/static/js/topologies.js
@@ -1067,8 +1067,34 @@
});
var setState = this.setState.bind(this);
- const headings = ["Bolt", "Parallelism", "Execute Count", "Failure Count",
- "Capacity Utilization(min)", "Capacity Utilization(max)"];
+ const headings = [
+ { name: "Bolt", sortable: true },
+ { name: "Parallelism", sortable: true },
+ { name: "Execute Count", sortable: true },
+ { name: "Failure Count", sortable: true },
+ { name: "Capacity Utilization(min)", sortable: true },
+ { name: "Capacity Utilization(max)", sortable: true },
+ { name: "Parallelism Calculator", sortable: false }
+ ];
+
+ var openParallelismCalculator = function (e, index) {
+ var row = rows[index];
+
+ var calculator = $("#parallelism-calculator-modal");
+ calculator.find('#modal-component').text(row[0]);
+ calculator.attr('data-execute-count', row[2]);
+ calculator.find('#modal-execute-count').text(row[2]);
+ calculator.find('#target-execute-count').val(row[2]);
+ calculator.attr('data-max-utilization', row[5].replace("%", ""));
+ calculator.find('#modal-max-utilization').text(row[5]);
+ calculator.find('#target-max-utilization').val(row[5].replace("%", ""));
+ calculator.attr('data-parallelism', row[1]);
+ calculator.find('#modal-parallelism').text(row[1]);
+ calculator.find('#target-parallelism').val(row[1]);
+
+ calculator.modal({keyboard: true});
+ };
+
return (
<div id="componentrunninginfo">
<div className="widget-header">
@@ -1100,16 +1126,27 @@
reverse: i === sortKey ? (!reverse) : true
});
}
- return <th key={i} className={classNameVals} onClick={clicked}>{heading}</th>;
+
+ if (heading.sortable) {
+ return <th key={i} className={classNameVals} onClick={clicked}>{heading.name}</th>;
+ } else {
+ return <th key={i}>{heading.name}</th>;
+ }
})}
</tr>
</thead>
<tbody>
- {rows.map(function (row) {
+ {rows.map(function (row, index) {
return <tr key={row[0]}>{
- row.map(function (value, i) {
- return <td className="col-md-2" key={i}>{value}</td>;
- })}</tr>;
+ row.map(function (value, i) {
+ return <td className="col-md-2" key={i}>{value}</td>;
+ })}
+ <td className="col-md-1">
+ <button type="button" className="btn btn-primary btn-xs" data-toggle="modal"
+ onClick={(e) => openParallelismCalculator(e, index)}>
+ Calculator
+ </button>
+ </td></tr>;
})}
</tbody>
</table>
diff --git a/heron/tools/ui/resources/templates/topology.html b/heron/tools/ui/resources/templates/topology.html
index f743c78..c109625 100644
--- a/heron/tools/ui/resources/templates/topology.html
+++ b/heron/tools/ui/resources/templates/topology.html
@@ -182,7 +182,49 @@
<div class="col-md-12">
<div id="display-counters"></div>
</div>
+ <!-- Popup dialog for parallelism calculator -->
+ <div class="modal fade" id="parallelism-calculator-modal" tabindex="-1" role="dialog" aria-labelledby="parallelismCalculatorModalLabel" aria-hidden="true">
+ <div class="modal-dialog modal-sm" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="exampleModalLabel">Parallelism Calculator: <span id="modal-component"></span></h5>
+ </div>
+ <div class="modal-body">
+ <form class="form-horizontal">
+ <h3 id="modal-component"></h3>
+ <div class="form-group">
+ <label class="col-sm-8 control-label" for="target-execute-count">
+ Target execute count (current: <b id="modal-execute-count"></b>)</label>
+ <div class="col-sm-4">
+ <input id="target-execute-count" class="form-control form-control-sm" value="100"></input>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-8 control-label" for="target-max-utilization">
+ Target max capacity utilization (current: <b id="modal-max-utilization"></b>)</label>
+ <div class="col-sm-3">
+ <input id="target-max-utilization" class="form-control form-control-sm" value=50 max=100 min=1></input>
+ </div>
+ <span class="col-sm-1 control-label">%</span>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-8 control-label" for="target-parallelism">
+ Target parallelism (current: <b id="modal-parallelism"></b>)</label>
+ <div class="col-sm-4">
+ <input id="target-parallelism" class="form-control form-control-sm" readonly=true value="3"></input>
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" onclick="calculateParallelism()">Calculate</button>
+ <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
+
<!-- Config -->
<div class="col-md-12">
<div class="col-md-12">
@@ -205,6 +247,23 @@
<script type="text/jsx" src="{{ static_url('js/config.js') }}"></script>
<script type="application/javascript">
+ function calculateParallelism() {
+ var calculator = $("#parallelism-calculator-modal");
+
+ var execute_count = calculator.attr("data-execute-count");
+ var max_utilization = calculator.attr("data-max-utilization");
+ var parallelism = calculator.attr("data-parallelism");
+ var target_execute_count = calculator.find('#target-execute-count').val();
+ var target_max_utilization = calculator.find('#target-max-utilization').val();
+
+ // Estimate the target parallelism based on the current information.
+ var newParallelism = max_utilization * target_execute_count * parallelism /
+ (execute_count * target_max_utilization);
+ calculator.find('#target-parallelism').val(Math.ceil(newParallelism));
+ }
+</script>
+
+<script type="application/javascript">
// colors used shading nodes in logical and physical plan
var colors = [