demo html/css/js modifications, web service and worker web service
This commit is contained in:
parent
4ce5751c11
commit
7f45cf12bc
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,3 +10,4 @@ memgraph
|
||||
*~
|
||||
*.pyc
|
||||
*.breakpoint
|
||||
*.session.yaml
|
||||
|
@ -1,10 +1,16 @@
|
||||
|
||||
body {
|
||||
font-family: GillSans, Calibri, Trebuchet, sans-serif;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.w100 {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 90%;
|
||||
color: #007FFF;
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
@ -15,3 +21,15 @@ body {
|
||||
svg, text {
|
||||
font-size: 28;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-color: #007FFF;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #007FFF;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
background-color: #007FFF;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
<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 href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="stylesheet" href="cypher/codemirror.css">
|
||||
<link rel="stylesheet" href="cypher/neo.css">
|
||||
|
||||
@ -14,17 +15,28 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- title row -->
|
||||
<div class="row">
|
||||
<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>
|
||||
|
||||
<!-- neo4j cards -->
|
||||
<div class="row">
|
||||
<div class="col s2">
|
||||
<div id="q1" class="card">
|
||||
<div id="q-0-0" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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"
|
||||
@ -33,10 +45,10 @@
|
||||
</div>
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
<div id="q2" class="card">
|
||||
<div id="q-0-1" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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"
|
||||
@ -45,10 +57,10 @@
|
||||
</div>
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
<div id="q3" class="card">
|
||||
<div id="q-0-2" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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"
|
||||
@ -57,10 +69,22 @@
|
||||
</div>
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
<div id="q4" class="card">
|
||||
<div id="q-0-3" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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 class="col s6">
|
||||
<canvas id="gauge" width="150" height="60"
|
||||
@ -70,20 +94,24 @@
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- the graph -->
|
||||
<div class="col s8">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div id="chart" style="height: 600px;">
|
||||
<div id="chart" style="height: 750px;">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- memgraph cards -->
|
||||
<div class="col s2">
|
||||
<div id="q5" class="card">
|
||||
<div id="q-1-0" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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"
|
||||
@ -92,10 +120,10 @@
|
||||
</div>
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
<div id="q6" class="card">
|
||||
<div id="q-1-1" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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"
|
||||
@ -104,10 +132,10 @@
|
||||
</div>
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
<div id="q7" class="card">
|
||||
<div id="q-1-2" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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"
|
||||
@ -116,10 +144,22 @@
|
||||
</div>
|
||||
<textarea id="query">MATCH (n:Person) RETURN n</textarea>
|
||||
</div>
|
||||
<div id="q8" class="card">
|
||||
<div id="q-1-3" class="card">
|
||||
<div class="qps valign-wrapper">
|
||||
<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 class="col s6">
|
||||
<canvas id="gauge" width="150" height="60"
|
||||
|
@ -90,46 +90,81 @@
|
||||
this.gauge.set(value);
|
||||
}
|
||||
|
||||
set(value) {
|
||||
set_value(value) {
|
||||
this.text.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
|
||||
let running = false;
|
||||
let value = 0;
|
||||
let maxQps = 15000;
|
||||
|
||||
let card1 = new QueryCard($('#q1')[0], maxQps);
|
||||
let card2 = new QueryCard($('#q2')[0], maxQps);
|
||||
let card3 = new QueryCard($('#q3')[0], maxQps);
|
||||
let card4 = new QueryCard($('#q4')[0], maxQps);
|
||||
let card5 = new QueryCard($('#q5')[0], maxQps);
|
||||
let card6 = new QueryCard($('#q6')[0], maxQps);
|
||||
let card7 = new QueryCard($('#q7')[0], maxQps);
|
||||
let card8 = new QueryCard($('#q8')[0], maxQps);
|
||||
// cards init
|
||||
let neo4jCards = [];
|
||||
let memgraphCards = [];
|
||||
queries.forEach(function(query, i) {
|
||||
query = put_new_line_mod_2(query.split(" ")).join('');
|
||||
neo4jCards.push(new QueryCard($('#q-0-' + i.toString())[0], maxQps));
|
||||
neo4jCards[i].set_query(query);
|
||||
memgraphCards.push(new QueryCard($('#q-1-' + i.toString())[0], maxQps));
|
||||
memgraphCards[i].set_query(query);
|
||||
});
|
||||
|
||||
// counters update
|
||||
// cards update
|
||||
function run() {
|
||||
if (!running)
|
||||
return;
|
||||
setTimeout(() => {
|
||||
value += 10;
|
||||
|
||||
if(value >= maxQps)
|
||||
value = 0;
|
||||
|
||||
card1.set(value);
|
||||
card2.set(value);
|
||||
card3.set(value);
|
||||
card4.set(value);
|
||||
card5.set(value);
|
||||
card6.set(value);
|
||||
card7.set(value);
|
||||
card8.set(value);
|
||||
|
||||
queries.forEach(function(query, i) {
|
||||
neo4jCards[i].set_value(Math.round(1000 + Math.random() * 3000));
|
||||
memgraphCards[i].set_value(Math.round(7000 + Math.random() * 7000));
|
||||
});
|
||||
run();
|
||||
}, 20);
|
||||
}, 1000);
|
||||
}
|
||||
run();
|
||||
|
||||
// graph init
|
||||
var data = [];
|
||||
@ -148,7 +183,7 @@
|
||||
|
||||
chart.yAxis
|
||||
.axisLabel('QPS')
|
||||
.tickFormat(d3.format(',r'));
|
||||
.tickFormat(d3.format('f'));
|
||||
|
||||
chartData = d3.select('#chart svg')
|
||||
.datum(data);
|
||||
@ -162,6 +197,8 @@
|
||||
// graph update
|
||||
let x = 0;
|
||||
function updateGraph() {
|
||||
if (!running)
|
||||
return;
|
||||
setTimeout(() => {
|
||||
x += 1;
|
||||
if (x > 100)
|
||||
@ -185,6 +222,5 @@
|
||||
updateGraph();
|
||||
}, 1000);
|
||||
}
|
||||
updateGraph();
|
||||
|
||||
})();
|
||||
|
34
demo/web_service.py
Normal file
34
demo/web_service.py
Normal 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)
|
91
demo/worker/worker_web_service.py
Normal file
91
demo/worker/worker_web_service.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user