magic-wormhole/misc/dump-timing.py

96 lines
3.7 KiB
Python

# To use the web() option, you should do:
# * cd misc
# * npm install vis zepto
from __future__ import print_function
import os, sys, time, json
streams = sys.argv[1:]
num_streams = len(streams)
labels = dict([(num, " "*num + "[%d]" % (num+1) + " "*(num_streams-1-num))
for num in range(num_streams)])
timeline = []
groups_out = []
for which,fn in enumerate(streams):
with open(fn, "rb") as f:
for (start, finish, what, start_d, finish_d) in json.load(f):
timeline.append( (start, finish, which, what, start_d, finish_d) )
print("%s is %s" % (labels[which], fn))
groups_out.append({"id": which, "content": fn,
"className": "group-%d" % which})
timeline.sort(key=lambda row: row[0])
first = timeline[0][0]
print("started at %s" % time.ctime(start))
viz_out = []
for num, (start, finish, which, what, start_d, finish_d) in enumerate(timeline):
delta = start - first
delta_s = "%.6f" % delta
start_d_str = ", ".join(["%s=%s" % (name, start_d[name])
for name in sorted(start_d)])
finish_d_str = ", ".join(["%s=%s" % (name, finish_d[name])
for name in sorted(finish_d)])
details_str = start_d_str
if finish_d_str:
details_str += "/" + finish_d_str
finish_str = ""
if finish is not None:
finish_str = " +%.6f" % (finish - start)
print("%9s: %s %s %s%s" % (delta_s, labels[which], what, details_str,
finish_str))
viz_start = start*1000
viz_end = None if finish is None else finish*1000
viz_type = "range" if finish else "point"
if what == "wormhole started" or what == "wormhole":
viz_type = "background"
viz_content = '<span title="%s">%s</span>' % (details_str or "(No details)",
what) # sigh
viz_className = "item-group-%d" % which
if "waiting" in start_d:
viz_className += " wait-%s" % start_d["waiting"]
viz_out.append({"id": num, "start": viz_start, "end": viz_end,
"group": which, "content": viz_content,
"className": viz_className, # or style:
"type": viz_type,
})
here = os.path.dirname(__file__)
web_root = os.path.join(here, "web")
vis_root = os.path.join(here, "node_modules", "vis", "dist")
zepto_root = os.path.join(here, "node_modules", "zepto")
if not os.path.isdir(vis_root) or not os.path.isdir(zepto_root):
print("Cannot find 'vis' and 'zepto' in misc/node_modules/")
print("Please run 'npm install vis zepto' from the misc/ directory.")
sys.exit(1)
def web():
# set up a server that serves web/ at the root, plus a /data.json built
# from {timeline}. Quit when it fetches /done .
from twisted.web import resource, static, server
from twisted.internet import reactor, endpoints
ep = endpoints.serverFromString(reactor, "tcp:8066:interface=127.0.0.1")
root = static.File(web_root)
data_json = {"items": viz_out, "groups": groups_out}
data = json.dumps(data_json).encode("utf-8")
root.putChild("data.json", static.Data(data, "application/json"))
root.putChild("vis", static.File(vis_root))
root.putChild("zepto", static.File(zepto_root))
class Shutdown(resource.Resource):
def render_GET(self, request):
print("timeline ready, server shutting down")
reactor.stop()
return "shutting down"
root.putChild("done", Shutdown())
site = server.Site(root)
ep.listen(site)
import webbrowser
def launch_browser():
webbrowser.open("http://localhost:%d/timeline.html" % 8066)
print("browser opened, waiting for shutdown")
reactor.callLater(0, launch_browser)
reactor.run()
web()