demo html/css/js modifications, web service and worker web service

This commit is contained in:
Marko Budiselic 2016-03-19 04:07:54 +01:00
parent 4ce5751c11
commit 7f45cf12bc
6 changed files with 264 additions and 44 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ memgraph
*~ *~
*.pyc *.pyc
*.breakpoint *.breakpoint
*.session.yaml

View File

@ -1,10 +1,16 @@
body { body {
font-family: GillSans, Calibri, Trebuchet, sans-serif;
background-color: #eee; background-color: #eee;
} }
.w100 { .w100 {
width: 100%; width: 100%;
}
.title {
width: 90%;
color: #007FFF;
} }
.CodeMirror { .CodeMirror {
@ -15,3 +21,15 @@ body {
svg, text { svg, text {
font-size: 28; font-size: 28;
} }
.btn {
background-color: #007FFF;
}
.btn:hover {
background-color: #007FFF;
}
.btn:focus {
background-color: #007FFF;
}

View File

@ -6,6 +6,7 @@
<link rel="stylesheet" href="demo.css"> <link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="cypher/codemirror.css"> <link rel="stylesheet" href="cypher/codemirror.css">
<link rel="stylesheet" href="cypher/neo.css"> <link rel="stylesheet" href="cypher/neo.css">
@ -14,17 +15,28 @@
</head> </head>
<body> <body>
<!-- title row -->
<div class="row"> <div class="row">
<div class="valign-wrapper"> <div class="valign-wrapper">
<h1 class="valign center w100">Memgraph Benchmark</h1> <h1 class="valign center title">Memgraph Benchmark</h1>
<span>
<button id="running-button"
class="btn waves-effect waves-light"
type="submit" name="action">
Start
</button>
</span>
</div> </div>
</div> </div>
<!-- neo4j cards -->
<div class="row"> <div class="row">
<div class="col s2"> <div class="col s2">
<div id="q1" class="card"> <div id="q-0-0" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -33,10 +45,10 @@
</div> </div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
<div id="q2" class="card"> <div id="q-0-1" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -45,10 +57,10 @@
</div> </div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
<div id="q3" class="card"> <div id="q-0-2" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -57,10 +69,22 @@
</div> </div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
<div id="q4" class="card"> <div id="q-0-3" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div>
<div class="col s6">
<canvas id="gauge" width="150" height="60"
class="valign center"></canvas>
</div>
</div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div>
<div id="q-0-4" class="card">
<div class="qps valign-wrapper">
<div class="col s6">
<h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -70,20 +94,24 @@
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
</div> </div>
<!-- the graph -->
<div class="col s8"> <div class="col s8">
<div class="card"> <div class="card">
<div class="card-content"> <div class="card-content">
<div id="chart" style="height: 600px;"> <div id="chart" style="height: 750px;">
<svg></svg> <svg></svg>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- memgraph cards -->
<div class="col s2"> <div class="col s2">
<div id="q5" class="card"> <div id="q-1-0" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -92,10 +120,10 @@
</div> </div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
<div id="q6" class="card"> <div id="q-1-1" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -104,10 +132,10 @@
</div> </div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
<div id="q7" class="card"> <div id="q-1-2" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"
@ -116,10 +144,22 @@
</div> </div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea> <textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div> </div>
<div id="q8" class="card"> <div id="q-1-3" class="card">
<div class="qps valign-wrapper"> <div class="qps valign-wrapper">
<div class="col s6"> <div class="col s6">
<h3 id="text" class="valign center w100">25734</h3> <h3 id="text" class="valign center w100">0</h3>
</div>
<div class="col s6">
<canvas id="gauge" width="150" height="60"
class="valign center"></canvas>
</div>
</div>
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
</div>
<div id="q-1-4" class="card">
<div class="qps valign-wrapper">
<div class="col s6">
<h3 id="text" class="valign center w100">0</h3>
</div> </div>
<div class="col s6"> <div class="col s6">
<canvas id="gauge" width="150" height="60" <canvas id="gauge" width="150" height="60"

View File

@ -90,46 +90,81 @@
this.gauge.set(value); this.gauge.set(value);
} }
set(value) { set_value(value) {
this.text.set(value); this.text.set(value);
this.gauge.set(value); this.gauge.set(value);
} }
set_query(query) {
this.query.set(query);
}
} }
var put_new_line_mod_2 = function(array) {
let join_array = array.map(function(o, i) {
if (i % 2 == 0)
return ' ';
else
return '\n';
});
join_array.pop();
return array.map(function(v,i) {
return [v, join_array[i]];
}).reduce(function(a,b) {
return a.concat(b);
});
};
var queries = [
"CREATE (n{id:@}) RETURN n",
"MATCH (n{id:#}),(m{id:#}) CREATE (n)-[r:test]->(m) RETURN r",
"MATCH (n{id:#}) SET n.prop=^ RETURN n",
"MATCH (n{id:#}) RETURN n",
"MATCH (n{id:#})-[r]->(m) RETURN count(r)"
];
$("#running-button").click(function() {
running = !running;
if (running) {
$(this).text('STOP');
run();
updateGraph();
}
if (!running)
$(this).text('START');
});
// counters init // counters init
let running = false;
let value = 0; let value = 0;
let maxQps = 15000; let maxQps = 15000;
let card1 = new QueryCard($('#q1')[0], maxQps); // cards init
let card2 = new QueryCard($('#q2')[0], maxQps); let neo4jCards = [];
let card3 = new QueryCard($('#q3')[0], maxQps); let memgraphCards = [];
let card4 = new QueryCard($('#q4')[0], maxQps); queries.forEach(function(query, i) {
let card5 = new QueryCard($('#q5')[0], maxQps); query = put_new_line_mod_2(query.split(" ")).join('');
let card6 = new QueryCard($('#q6')[0], maxQps); neo4jCards.push(new QueryCard($('#q-0-' + i.toString())[0], maxQps));
let card7 = new QueryCard($('#q7')[0], maxQps); neo4jCards[i].set_query(query);
let card8 = new QueryCard($('#q8')[0], maxQps); memgraphCards.push(new QueryCard($('#q-1-' + i.toString())[0], maxQps));
memgraphCards[i].set_query(query);
});
// counters update // cards update
function run() { function run() {
if (!running)
return;
setTimeout(() => { setTimeout(() => {
value += 10; value += 10;
if(value >= maxQps) if(value >= maxQps)
value = 0; value = 0;
queries.forEach(function(query, i) {
card1.set(value); neo4jCards[i].set_value(Math.round(1000 + Math.random() * 3000));
card2.set(value); memgraphCards[i].set_value(Math.round(7000 + Math.random() * 7000));
card3.set(value); });
card4.set(value);
card5.set(value);
card6.set(value);
card7.set(value);
card8.set(value);
run(); run();
}, 20); }, 1000);
} }
run();
// graph init // graph init
var data = []; var data = [];
@ -148,7 +183,7 @@
chart.yAxis chart.yAxis
.axisLabel('QPS') .axisLabel('QPS')
.tickFormat(d3.format(',r')); .tickFormat(d3.format('f'));
chartData = d3.select('#chart svg') chartData = d3.select('#chart svg')
.datum(data); .datum(data);
@ -162,6 +197,8 @@
// graph update // graph update
let x = 0; let x = 0;
function updateGraph() { function updateGraph() {
if (!running)
return;
setTimeout(() => { setTimeout(() => {
x += 1; x += 1;
if (x > 100) if (x > 100)
@ -185,6 +222,5 @@
updateGraph(); updateGraph();
}, 1000); }, 1000);
} }
updateGraph();
})(); })();

34
demo/web_service.py Normal file
View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
from flask import Flask
class WebService(Flask):
def __init__(self):
'''
'''
self.server = Flask(__name__)
def add_route(self, route, code_method, http_method):
'''
Registers URL rule
:param route: str, route string
:param object_method: object method responsible for the
request handling
:param http_method: name of http method
'''
self.server.add_url_rule(route, '%s_%s' % (route, http_method),
code_method, methods=[http_method])
def setup_routes(self):
'''
'''
self.add_route('/ping', self.ping, 'GET')
def ping(self):
'''
Ping endpoint. Returns 204 HTTP status code.
'''
return ('', 204)

View File

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
import logging
import threading
from flask import request, jsonify
from .. import WebService
from . import wrapped_client
log = logging.getLogger(__name__)
class WorkerWebServer(WebService):
'''
Memgraph worker web server. For now it wraps the flask server.
'''
def __init__(self):
'''
Instantiates the flask web server.
'''
super().__init__()
self.params_data = None
self.is_simulation_running = False
self.stats_data = None
self.setup_routes()
def setup_routes(self):
'''
Setup all routes.
'''
super().__init__()
self.add_route('/start', self.start, 'POST')
self.add_route('/stop', self.stop, 'POST')
self.add_route('/stats', self.stats, 'GET')
self.add_route('/params', self.params_get, 'GET')
self.add_route('/params', self.params_set, 'POST')
def run_simulation(self):
'''
If flag is_simulation_running flag is up (True) the executor
epoch will be executed. Epochs will be executed until somebody
set is_simulation_running flag to Flase.
'''
log.info('new simulation run')
while self.is_simulation_running:
self.stats_data = wrapped_client(*self.params_data)
def start(self):
'''
'''
self.is_simulation_running = True
t = threading.Thread(target=self.run_simulation, daemon=True)
t.start()
return ('', 204)
def stop(self):
'''
'''
self.is_simulation_running = False
return ('', 204)
def stats(self):
'''
Returns the simulation stats. Queries per second.
'''
if not self.stats_data:
return ('', 204)
return jsonify(self.stats_data)
def params_get(self):
'''
Returns simulation parameters.
'''
return jsonify(self.simulation_params.json_data())
def params_set(self):
'''
Sets simulation parameters.
'''
data = request.get_json()
param_names = ['host', 'port', 'connections', 'duration', 'queries']
for param in param_names:
if param in data:
setattr(self.params_data, param, data[param])
return self.params_get()