Changeset - 3b755a58a8b5
[Not reviewed]
default
0 2 0
Laman - 7 years ago 2017-10-31 22:51:38

resettable stats
2 files changed with 19 insertions and 9 deletions:
0 comments (0 inline, 0 general)
src/morevna.py
Show inline comments
 
import sys
 
import os.path
 
import logging as log
 
from argparse import ArgumentParser
 

	
 
from util import spawnDaemon, splitHost
 
import config as conf
 
import stats
 
from hashtree import HashTree
 
from client import Client, Connection as ClientConnection, FailedConnection
 
from server import Miniserver
 

	
 

	
 
def _checkFile(f):
 
	if not os.path.isfile(f):
 
		print("invalid file specified:",f,file=sys.stderr)
 
		sys.exit(1)
 

	
 

	
 
def buildTree(args):
 
	_checkFile(args.datafile)
 
	if os.path.isfile(args.treefile):
 
		treeMod=os.stat(args.treefile).st_mtime
 
		dataMod=os.stat(args.datafile).st_mtime
 
		if dataMod<treeMod and not args.force:
 
			print("tree file is up to date")
 
			return
 

	
 
	tree=HashTree.fromFile(args.datafile)
 
	tree.save(args.treefile)
 

	
 
def push(args):
 
	_checkFile(args.datafile)
 
	if args.tree:
 
		_checkFile(args.tree)
 
	if args.host: conf.hosts=[args.host]
 
	if args.port: conf.port=args.port
 

	
 
	c=Client(args.datafile,args.tree)
 
	for h in conf.hosts:
 
		host=splitHost(h,conf.port)
 
		stats.reset()
 
		try:
 
			with ClientConnection(*host) as con:
 
				c.setConnection(con)
 
				blocksToTransfer=c.negotiate()
 
				c.sendData(blocksToTransfer)
 
			print()
 
			print(stats.report())
 
			print()
 
		except FailedConnection: continue
 

	
 
def pull(args):
 
	_checkFile(args.datafile)
 
	if args.tree:
 
		_checkFile(args.tree)
 
	if args.host: conf.hosts=[args.host]
 
	if args.port: conf.port=args.port
 

	
 
	c=Client(args.datafile,args.tree)
 
	host=splitHost(conf.hosts[0],conf.port)
 
	try:
 
		with ClientConnection(*host) as con:
 
			c.setConnection(con)
 
			blocksToTransfer=c.negotiate()
 
			c.pullData(blocksToTransfer)
 
		print()
 
		print(stats.report())
 
	except FailedConnection: pass
 

	
 
def serve(args):
 
	_checkFile(args.datafile)
 
	if args.tree:
 
		_checkFile(args.tree)
 
	if args.host: conf.hosts.insert(0,args.host)
 
	if args.port: conf.port=args.port
 

	
 
	s=Miniserver(args.datafile,args.tree)
 
	try:
 
		spawnDaemon(s.serve)
 
	except Exception as e:
 
		log.exception("exception: %s",e)
 

	
 

	
 
parser=ArgumentParser()
 
subparsers=parser.add_subparsers()
 

	
 
pBuild=subparsers.add_parser("build")
 
pBuild.add_argument("-f","--force",action="store_true",help="force tree rebuild")
 
pBuild.add_argument("treefile", help="stored hash tree location")
 
pBuild.add_argument("datafile")
 
pBuild.set_defaults(func=buildTree)
 

	
 
pUpdate=subparsers.add_parser("push")
 
pUpdate.add_argument("-p","--port",type=int)
 
pUpdate.add_argument("--host")
 
pUpdate.add_argument("-t","--tree",help="stored hash tree location")
 
pUpdate.add_argument("datafile")
 
pUpdate.set_defaults(func=push)
 

	
 
pUpdate=subparsers.add_parser("pull")
 
pUpdate.add_argument("-p","--port",type=int)
 
pUpdate.add_argument("--host")
 
pUpdate.add_argument("-t","--tree",help="stored hash tree location")
 
pUpdate.add_argument("datafile")
 
pUpdate.set_defaults(func=pull)
 

	
 
pServe=subparsers.add_parser("serve")
 
pServe.add_argument("-p","--port",type=int)
 
pServe.add_argument("--host")
 
pServe.add_argument("-t","--tree",help="stored hash tree location")
 
pServe.add_argument("datafile")
 
pServe.set_defaults(func=serve)
 

	
 
args=parser.parse_args()
 
args.func(args)
src/stats.py
Show inline comments
 
class Stats:
 
	received=0
 
	sent=0
 
	exchangedNodes=0
 
	transferredBlocks=0
 
	def __init__(self):
 
		self.received=0
 
		self.sent=0
 
		self.exchangedNodes=0
 
		self.transferredBlocks=0
 

	
 
stats=Stats()
 

	
 

	
 
def logReceived(data):
 
	Stats.received+=len(data)
 
	stats.received+=len(data)
 

	
 

	
 
def logSent(data):
 
	Stats.sent+=len(data)
 
	stats.sent+=len(data)
 

	
 

	
 
def logExchangedNode(k=1):
 
	Stats.exchangedNodes+=k
 
	stats.exchangedNodes+=k
 

	
 

	
 
def logTransferredBlock():
 
	Stats.transferredBlocks+=1
 
	stats.transferredBlocks+=1
 

	
 

	
 
def reset():
 
	global stats
 
	stats=Stats()
 

	
 

	
 
def report():
 
	return """received {rf} ({r:,} B)
 
sent {sf} ({s:,} B)
 
exchanged {nodes:,} hash tree nodes
 
transferred {blocks:,} blocks""".format(rf=formatBytes(Stats.received), r=Stats.received, sf=formatBytes(Stats.sent), s=Stats.sent, nodes=Stats.exchangedNodes, blocks=Stats.transferredBlocks)
 
transferred {blocks:,} blocks""".format(rf=formatBytes(stats.received), r=stats.received, sf=formatBytes(stats.sent), s=stats.sent, nodes=stats.exchangedNodes, blocks=stats.transferredBlocks)
 

	
 

	
 
def formatBytes(x):
 
	exts=["B","kiB","MiB","GiB","TiB","PiB"]
 
	i=0
 
	while x>1024:
 
		x/=1024
 
		i+=1
 
	if x>=100: x=round(x)
 
	elif x>=10: x=round(x,1)
 
	else: x=round(x,2)
 
	return "{0} {1}".format(x,exts[i])
0 comments (0 inline, 0 general)