epicyon/fitnessFunctions.py

133 lines
4.5 KiB
Python
Raw Normal View History

2021-10-19 13:41:48 +00:00
__filename__ = "fitnessFunctions.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.2.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
2021-10-19 20:08:24 +00:00
import os
2021-10-19 13:41:48 +00:00
import time
2021-10-19 20:08:24 +00:00
from webapp_utils import htmlHeaderWithExternalStyle
from webapp_utils import htmlFooter
from utils import getConfigParam
2021-10-19 17:35:52 +00:00
from utils import saveJson
2021-10-19 13:41:48 +00:00
def fitnessPerformance(startTime, fitnessState: {},
fitnessId: str, watchPoint: str, debug: bool) -> None:
"""Log a performance watchpoint
"""
if 'performance' not in fitnessState:
fitnessState['performance'] = {}
if fitnessId not in fitnessState['performance']:
fitnessState['performance'][fitnessId] = {}
2021-10-19 18:08:18 +00:00
if watchPoint not in fitnessState['performance'][fitnessId]:
fitnessState['performance'][fitnessId][watchPoint] = {
2021-10-19 18:12:48 +00:00
"total": float(0),
"ctr": int(0)
2021-10-19 18:08:18 +00:00
}
2021-10-19 13:41:48 +00:00
2021-10-19 18:12:48 +00:00
timeDiff = float(time.time() - startTime)
2021-10-19 13:41:48 +00:00
2021-10-19 18:08:18 +00:00
fitnessState['performance'][fitnessId][watchPoint]['total'] += timeDiff
fitnessState['performance'][fitnessId][watchPoint]['ctr'] += 1
if fitnessState['performance'][fitnessId][watchPoint]['ctr'] >= 1024:
fitnessState['performance'][fitnessId][watchPoint]['total'] /= 2
fitnessState['performance'][fitnessId][watchPoint]['ctr'] = \
int(fitnessState['performance'][fitnessId][watchPoint]['ctr'] / 2)
2021-10-19 13:41:48 +00:00
if debug:
2021-10-19 18:08:18 +00:00
ctr = fitnessState['performance'][fitnessId][watchPoint]['ctr']
total = fitnessState['performance'][fitnessId][watchPoint]['total']
2021-10-19 13:41:48 +00:00
print('FITNESS: performance/' + fitnessId + '/' +
2021-10-19 18:08:18 +00:00
watchPoint + '/' + str(total * 1000 / ctr))
2021-10-19 17:35:52 +00:00
2021-10-19 20:08:24 +00:00
def sortedWatchPoints(fitness: {}, fitnessId: str) -> []:
"""Returns a sorted list of watchpoints
2021-10-19 20:58:59 +00:00
times are in mS
2021-10-19 20:08:24 +00:00
"""
2021-10-19 20:46:29 +00:00
if not fitness.get('performance'):
return []
if not fitness['performance'].get(fitnessId):
2021-10-19 20:08:24 +00:00
return []
result = []
2021-10-19 20:46:29 +00:00
for watchPoint, item in fitness['performance'][fitnessId].items():
2021-10-19 20:08:24 +00:00
if not item.get('total'):
continue
2021-10-20 15:51:48 +00:00
averageTime = item['total'] * 1000 / item['ctr']
averageTimeStr = str(averageTime)
threshold = 10
while threshold < 100000:
if averageTime < threshold:
averageTimeStr = '0' + averageTimeStr
threshold *= 10
2021-10-20 15:48:19 +00:00
result.append(averageTimeStr + ' ' + watchPoint)
2021-10-19 20:08:24 +00:00
result.sort(reverse=True)
return result
def htmlWatchPointsGraph(baseDir: str, fitness: {}, fitnessId: str,
maxEntries: int) -> str:
"""Returns the html for a graph of watchpoints
"""
watchPointsList = sortedWatchPoints(fitness, fitnessId)
cssFilename = baseDir + '/epicyon-graph.css'
if os.path.isfile(baseDir + '/graph.css'):
cssFilename = baseDir + '/graph.css'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
htmlStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
htmlStr += \
'<table class="graph">\n' + \
'<caption>Watchpoints for ' + fitnessId + '</caption>\n' + \
'<thead>\n' + \
' <tr>\n' + \
' <th scope="col">Item</th>\n' + \
' <th scope="col">Percent</th>\n' + \
' </tr>\n' + \
'</thead><tbody>\n'
# get the maximum time
2021-10-19 20:58:59 +00:00
maxAverageTime = float(1)
2021-10-19 20:08:24 +00:00
if len(watchPointsList) > 0:
maxAverageTime = float(watchPointsList[0].split(' ')[0])
for watchPoint in watchPointsList:
averageTime = float(watchPoint.split(' ')[0])
if averageTime > maxAverageTime:
maxAverageTime = averageTime
ctr = 0
for watchPoint in watchPointsList:
name = watchPoint.split(' ', 1)[1]
2021-10-19 20:08:24 +00:00
averageTime = float(watchPoint.split(' ')[0])
heightPercent = int(averageTime * 100 / maxAverageTime)
2021-10-19 20:58:59 +00:00
timeMS = int(averageTime)
2021-10-19 21:12:06 +00:00
if heightPercent == 0:
continue
2021-10-19 20:08:24 +00:00
htmlStr += \
'<tr style="height:' + str(heightPercent) + '%">\n' + \
' <th scope="row">' + name + '</th>\n' + \
' <td><span>' + str(timeMS) + 'mS</span></td>\n' + \
'</tr>\n'
ctr += 1
if ctr >= maxEntries:
break
htmlStr += '</tbody></table>\n' + htmlFooter()
return htmlStr
2021-10-19 17:35:52 +00:00
def fitnessThread(baseDir: str, fitness: {}):
"""Thread used to save fitness function scores
"""
fitnessFilename = baseDir + '/accounts/fitness.json'
while True:
# every 10 mins
time.sleep(60 * 10)
saveJson(fitness, fitnessFilename)