backend.simplemonitor   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 76
dl 0
loc 116
rs 10
c 0
b 0
f 0
wmc 13

5 Functions

Rating   Name   Duplication   Size   Complexity  
A getstats() 0 4 1
A run_tasks() 0 21 2
A process_results() 0 7 2
A getminers() 0 9 3
B process_result() 0 41 5
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 = 1
13
MINER_MULTIPLIER = 1
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
    '''poll miner'''
21
    minerstats, minerinfo, statspolling, minerpool = antminerhelper.stats(miner)
22
    return miner, minerstats, minerinfo, statspolling, minerpool
23
24
def process_results(results):
25
    '''process all results'''
26
    totaltime = 0
27
    for miner, minerstats, minerinfo, statspolling, minerpool in results:
28
        totaltime += statspolling.elapsed() * 1000
29
        process_result(miner, minerstats, minerinfo, statspolling, minerpool)
30
    return totaltime
31
32
def process_result(miner, minerstats, minerinfo, statspolling, minerpool):
33
    '''process results from one polling'''
34
    if minerstats is None:
35
        APP.logerror('{0} Offline? {1}'.format(miner.name, miner.ipaddress))
36
    else:
37
        savedminer = APP.getminer(miner)
38
        if not savedminer:
39
            print('Could not find saved miner {0}'.format(miner.name))
40
            savedminer = miner
41
        poolname = '{0} {1}'.format(minerpool.currentpool, minerpool.currentworker)
42
        foundpool = APP.pools.findpool(minerpool)
43
        if foundpool is not None:
44
            minerpool.poolname = foundpool.name
45
        savedminer.monitored(minerstats, minerpool, minerinfo, statspolling.elapsed())
46
        print('{0} mining at {1}({2})'.format(savedminer.name, minerpool.poolname, poolname))
47
48
        print(Fore.CYAN + str(APP.now()), miner.name, miner.status, \
49
            str(minerstats.currenthash), str(minerstats.minercount), \
50
            'temp=' + str(minerstats.tempboardmax()), \
51
            savedminer.uptime(minerstats.elapsed), \
52
            '{0:d}ms'.format(int(savedminer.monitorresponsetime() * 1000)))
53
54
        ##switches miner to default pool
55
        #if miner.defaultpool:
56
        #    founddefault = next((p for p in POOLS if p.name == miner.defaultpool), None)
57
        #    if founddefault is not None:
58
        #        #minerpool = antminerhelper.pools(miner)
59
        #        if minerpool is not None:
60
        #            #find pool number of default pool and switch to it
61
        #            switchtopoolnumber = minerpool.findpoolnumberforpool(founddefault.url,
62
        #founddefault.user)
63
        #            if switchtopoolnumber is not None and switchtopoolnumber > 0:
64
        #                antminerhelper.switch(miner, switchtopoolnumber)
65
        #                print(Fore.YELLOW + str(APP.now()), miner.name, 'switched to',
66
        #miner.defaultpool)
67
68
    #APP.putminerandstats(savedminer, minerstats, minerpool)
69
    #APP.updateknownminer(savedminer)
70
    if not statspolling:
71
        return 0
72
    return statspolling.elapsed() * 1000
73
74
def getminers(miners):
75
    '''get list of miners to poll'''
76
    listofminers = []
77
    cnt = MINER_MULTIPLIER
78
    while cnt > 0:
79
        for miner in miners:
80
            listofminers.append(miner)
81
        cnt -= 1
82
    return listofminers
83
84
async def run_tasks(cutor, miners):
85
    '''poll miners concurrently'''
86
    listofminers = getminers(miners)
87
    calltime = MinerApiCall(None)
88
    calltime.start()
89
    totalpolling = 0
90
    lop = asyncio.get_event_loop()
91
    tasks = [lop.run_in_executor(cutor, getstats, miner) for miner in listofminers]
92
93
    for fut in asyncio.as_completed(tasks, loop=lop):
94
        results = await fut
95
        totalpolling += process_result(*results)
96
97
    calltime.stop()
98
99
    totalms = int(calltime.elapsed()*1000)
100
    print('{0} api calls in {1}ms. Avg={2}ms' \
101
        .format(len(listofminers), totalms, totalms/len(listofminers)))
102
    timesavings = totalpolling - totalms
103
    print('Concurrency saved {}ms - {}ms = {}ms ({}%)' \
104
        .format(totalpolling, totalms, timesavings, int(timesavings/totalpolling*100)))
105
106
107
if __name__ == '__main__':
108
    MINERS = APP.knownminers()
109
    APP.print("{0} miners configured".format(len(MINERS)))
110
111
    CUTOR = ThreadPoolExecutor(max_workers=WORKER_THREADS)
112
    LOOP = asyncio.get_event_loop()
113
    LOOP.run_until_complete(run_tasks(CUTOR, MINERS))
114
    LOOP.close()
115
    APP.shutdown()
116
    #WHATISAID = input('done')
117