Passed
Push — master ( b92f2d...c77aa9 )
by Dave
01:03
created

backend.simplemonitor.process_result()   B

Complexity

Conditions 5

Size

Total Lines 38
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
nop 5
dl 0
loc 38
rs 8.9093
c 0
b 0
f 0
1
'''gets stats from a miner and serializes to disk'''
2
import asyncio
3
from concurrent.futures import ThreadPoolExecutor
4
from colorama import Fore
5
from backend.fcmapp import ApplicationService
6
from domain.mining import MinerApiCall
7
from helpers import antminerhelper
8
9
print('Starting...')
10
APP = ApplicationService(component='fullcycle')
11
APP.print('started app. getting known miners')
12
WORKER_THREADS = 10
13
MINER_MULTIPLIER = 10
14
15
#async def getstats_async(miner):
16
#    minerstats, minerinfo, statspolling, minerpool = await antminerhelper.stats(miner)
17
#    return minerstats, minerinfo, statspolling, minerpool
18
19
def getstats(miner):
20
    minerstats, minerinfo, statspolling, minerpool = antminerhelper.stats(miner)
21
    return miner, minerstats, minerinfo, statspolling, minerpool
22
23
def process_results(results):
24
    totaltime = 0
25
    for miner, minerstats, minerinfo, statspolling, minerpool in results:
26
        totaltime += statspolling.elapsed() * 1000
27
        process_result(miner, minerstats, minerinfo, statspolling, minerpool)
28
    return totaltime
29
30
def process_result(miner, minerstats, minerinfo, statspolling, minerpool):
31
    if minerstats is None:
32
        APP.logerror('{0} Offline? {1}'.format(miner.name, miner.ipaddress))
33
    else:
34
        savedminer = APP.getminer(miner)
35
        if not savedminer:
36
            print('Could not find saved miner {0}'.format(miner.name))
37
            savedminer = miner
38
        poolname = '{0} {1}'.format(minerpool.currentpool, minerpool.currentworker)
39
        foundpool = APP.pools.findpool(minerpool)
40
        if foundpool is not None:
41
            minerpool.poolname = foundpool.name
42
        savedminer.monitored(minerstats, minerpool, minerinfo, statspolling.elapsed())
43
        print('{0} mining at {1}({2})'.format(savedminer.name, minerpool.poolname, poolname))
44
45
        print(Fore.CYAN + str(APP.now()), miner.name, miner.status,
46
                str(minerstats.currenthash), str(minerstats.minercount),
47
                'temp=' + str(minerstats.tempboardmax()),
48
                savedminer.uptime(minerstats.elapsed),
49
                '{0:d}ms'.format(int(savedminer.monitorresponsetime() * 1000)))
50
51
        ##switches miner to default pool
52
        #if miner.defaultpool:
53
        #    founddefault = next((p for p in POOLS if p.name == miner.defaultpool), None)
54
        #    if founddefault is not None:
55
        #        #minerpool = antminerhelper.pools(miner)
56
        #        if minerpool is not None:
57
        #            #find pool number of default pool and switch to it
58
        #            switchtopoolnumber = minerpool.findpoolnumberforpool(founddefault.url, founddefault.user)
59
        #            if switchtopoolnumber is not None and switchtopoolnumber > 0:
60
        #                antminerhelper.switch(miner, switchtopoolnumber)
61
        #                print(Fore.YELLOW + str(APP.now()), miner.name, 'switched to', miner.defaultpool)
62
63
    #APP.putminerandstats(savedminer, minerstats, minerpool)
64
    #APP.updateknownminer(savedminer)
65
    if not statspolling:
66
        return 0
67
    return statspolling.elapsed() * 1000
68
69
def getminers(miners):
70
    listofminers = []
71
    cnt = MINER_MULTIPLIER
72
    while cnt > 0:
73
        for miner in miners:
74
            listofminers.append(miner)
75
        cnt -= 1
76
    return listofminers
77
78
async def run_tasks(cutor, miners):
79
    listofminers = getminers(miners)
80
    calltime = MinerApiCall(None)
81
    calltime.start()
82
    totalpolling = 0
83
    lop = asyncio.get_event_loop()
84
    tasks = [lop.run_in_executor(cutor, getstats, miner) for miner in listofminers]
85
86
    for fut in asyncio.as_completed(tasks, loop=lop):
87
        results = await fut
88
        totalpolling += process_result(*results)
89
90
    calltime.stop()
91
92
    totalms = int(calltime.elapsed()*1000)
93
    print('{0} api calls in {1}ms. Avg={2}ms'.format(len(listofminers), totalms, totalms/len(listofminers)))
94
    timesavings = totalpolling - totalms
95
    print('Concurrency saved {}ms - {}ms = {}ms ({}%)'.format(totalpolling, totalms, timesavings, int(timesavings/totalpolling*100)))
96
97
98
if __name__ == '__main__':
99
    MINERS = APP.knownminers()
100
    APP.print("{0} miners configured".format(len(MINERS)))
101
102
    cutor = ThreadPoolExecutor(max_workers=WORKER_THREADS)
103
    loop = asyncio.get_event_loop()
104
    loop.run_until_complete(run_tasks(cutor, MINERS))
105
    loop.close()
106
    APP.shutdown()
107
    WHATISAID = input('done')
108