added settings.py file for managing retries and "threads", as well as fixing some bugs in the APIs
This commit is contained in:
@@ -16,6 +16,7 @@ from config.bos import bos_config_convert, general_config_convert_bos
|
|||||||
|
|
||||||
from API import APIError
|
from API import APIError
|
||||||
|
|
||||||
|
from settings import CFG_UTIL_GET_VERSION_THREADS as GET_VERSION_THREADS
|
||||||
|
|
||||||
async def update_ui_with_data(key, data, append=False):
|
async def update_ui_with_data(key, data, append=False):
|
||||||
if append:
|
if append:
|
||||||
@@ -92,7 +93,6 @@ async def export_iplist(file_location, ip_list_selected):
|
|||||||
await update_ui_with_data("status", "")
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def send_config(ips: list, config):
|
async def send_config(ips: list, config):
|
||||||
await update_ui_with_data("status", "Configuring")
|
await update_ui_with_data("status", "Configuring")
|
||||||
tasks = []
|
tasks = []
|
||||||
@@ -101,8 +101,11 @@ async def send_config(ips: list, config):
|
|||||||
miners = await asyncio.gather(*tasks)
|
miners = await asyncio.gather(*tasks)
|
||||||
tasks = []
|
tasks = []
|
||||||
for miner in miners:
|
for miner in miners:
|
||||||
tasks.append(miner.send_config(config))
|
if len(tasks) < GET_VERSION_THREADS:
|
||||||
await asyncio.gather(*tasks)
|
tasks.append(miner.send_config(config))
|
||||||
|
else:
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
tasks = []
|
||||||
await update_ui_with_data("status", "")
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class BMMiner(BaseMiner):
|
|||||||
async def get_hostname(self) -> str:
|
async def get_hostname(self) -> str:
|
||||||
return "BMMiner Unknown"
|
return "BMMiner Unknown"
|
||||||
|
|
||||||
async def send_config(self):
|
async def send_config(self, _):
|
||||||
return None # ignore for now
|
return None # ignore for now
|
||||||
|
|
||||||
async def restart_backend(self) -> None:
|
async def restart_backend(self) -> None:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class BTMiner(BaseMiner):
|
|||||||
async def get_hostname(self) -> str:
|
async def get_hostname(self) -> str:
|
||||||
return "BTMiner Unknown"
|
return "BTMiner Unknown"
|
||||||
|
|
||||||
async def send_config(self):
|
async def send_config(self, _):
|
||||||
return None # ignore for now
|
return None # ignore for now
|
||||||
|
|
||||||
async def restart_backend(self) -> None:
|
async def restart_backend(self) -> None:
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ class CGMiner(BaseMiner):
|
|||||||
return data.stdout.strip()
|
return data.stdout.strip()
|
||||||
else:
|
else:
|
||||||
return "CGMiner Unknown"
|
return "CGMiner Unknown"
|
||||||
except Exception as e:
|
except Exception:
|
||||||
return "CGMiner Unknown"
|
return "CGMiner Unknown"
|
||||||
|
|
||||||
async def send_config(self):
|
async def send_config(self, _):
|
||||||
return None # ignore for now
|
return None # ignore for now
|
||||||
|
|
||||||
async def _get_ssh_connection(self) -> asyncssh.connect:
|
async def _get_ssh_connection(self) -> asyncssh.connect:
|
||||||
@@ -36,7 +36,7 @@ class CGMiner(BaseMiner):
|
|||||||
password=self.pwd,
|
password=self.pwd,
|
||||||
server_host_key_algs=['ssh-rsa'])
|
server_host_key_algs=['ssh-rsa'])
|
||||||
return conn
|
return conn
|
||||||
except asyncssh.misc.PermissionDenied as e:
|
except asyncssh.misc.PermissionDenied:
|
||||||
try:
|
try:
|
||||||
conn = await asyncssh.connect(str(self.ip),
|
conn = await asyncssh.connect(str(self.ip),
|
||||||
known_hosts=None,
|
known_hosts=None,
|
||||||
@@ -50,7 +50,6 @@ class CGMiner(BaseMiner):
|
|||||||
print(str(self.ip) + " Connection refused.")
|
print(str(self.ip) + " Connection refused.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def send_ssh_command(self, cmd):
|
async def send_ssh_command(self, cmd):
|
||||||
result = None
|
result = None
|
||||||
async with (await self._get_ssh_connection()) as conn:
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import asyncio
|
|||||||
import ipaddress
|
import ipaddress
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from settings import MINER_FACTORY_GET_VERSION_RETRIES as GET_VERSION_RETRIES
|
||||||
|
|
||||||
|
|
||||||
class MinerFactory:
|
class MinerFactory:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -19,11 +21,13 @@ class MinerFactory:
|
|||||||
if ip in self.miners:
|
if ip in self.miners:
|
||||||
return self.miners[ip]
|
return self.miners[ip]
|
||||||
# get the version data
|
# get the version data
|
||||||
version_data = await self._get_version_data(ip)
|
|
||||||
version = None
|
version = None
|
||||||
if version_data:
|
for i in range(GET_VERSION_RETRIES):
|
||||||
# if we got version data, get a list of the keys so we can check type of miner
|
version_data = await self._get_version_data(ip)
|
||||||
version = list(version_data['VERSION'][0].keys())
|
if version_data:
|
||||||
|
# if we got version data, get a list of the keys so we can check type of miner
|
||||||
|
version = list(version_data['VERSION'][0].keys())
|
||||||
|
break
|
||||||
if version:
|
if version:
|
||||||
# check version against different return miner types
|
# check version against different return miner types
|
||||||
if "BOSminer" in version or "BOSminer+" in version:
|
if "BOSminer" in version or "BOSminer+" in version:
|
||||||
@@ -35,9 +39,11 @@ class MinerFactory:
|
|||||||
elif "BTMiner" in version:
|
elif "BTMiner" in version:
|
||||||
miner = BTMiner(str(ip))
|
miner = BTMiner(str(ip))
|
||||||
else:
|
else:
|
||||||
|
print(f"Bad API response: {version}")
|
||||||
miner = UnknownMiner(str(ip))
|
miner = UnknownMiner(str(ip))
|
||||||
else:
|
else:
|
||||||
# if we don't get version, miner type is unknown
|
# if we don't get version, miner type is unknown
|
||||||
|
print(f"No API response: {str(ip)}")
|
||||||
miner = UnknownMiner(str(ip))
|
miner = UnknownMiner(str(ip))
|
||||||
# save the miner in cache
|
# save the miner in cache
|
||||||
self.miners[ip] = miner
|
self.miners[ip] = miner
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class UnknownMiner(BaseMiner):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Unknown: {str(self.ip)}"
|
return f"Unknown: {str(self.ip)}"
|
||||||
|
|
||||||
async def send_config(self):
|
async def send_config(self, _):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_hostname(self):
|
async def get_hostname(self):
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import ipaddress
|
import ipaddress
|
||||||
import asyncio
|
import asyncio
|
||||||
from miners.miner_factory import MinerFactory
|
from miners.miner_factory import MinerFactory
|
||||||
|
from settings import NETWORK_PING_RETRIES as PING_RETRIES, NETWORK_PING_TIMEOUT as PING_TIMEOUT, NETWORK_SCAN_THREADS as SCAN_THREADS
|
||||||
PING_RETRIES: int = 3
|
|
||||||
PING_TIMEOUT: int = 3
|
|
||||||
|
|
||||||
|
|
||||||
class MinerNetwork:
|
class MinerNetwork:
|
||||||
@@ -29,13 +27,18 @@ class MinerNetwork:
|
|||||||
return ipaddress.ip_network(f"{default_gateway}/{subnet_mask}", strict=False)
|
return ipaddress.ip_network(f"{default_gateway}/{subnet_mask}", strict=False)
|
||||||
|
|
||||||
async def scan_network_for_miners(self) -> None or list:
|
async def scan_network_for_miners(self) -> None or list:
|
||||||
"""Scan the network for miners, and use the miner factory to get correct types."""
|
"""Scan the network for miners, and """
|
||||||
local_network = self.get_network()
|
local_network = self.get_network()
|
||||||
print(f"Scanning {local_network} for miners...")
|
print(f"Scanning {local_network} for miners...")
|
||||||
scan_tasks = []
|
scan_tasks = []
|
||||||
|
miner_ips = []
|
||||||
for host in local_network.hosts():
|
for host in local_network.hosts():
|
||||||
scan_tasks.append(self.ping_miner(host))
|
if len(scan_tasks) < SCAN_THREADS:
|
||||||
miner_ips = await asyncio.gather(*scan_tasks)
|
scan_tasks.append(self.ping_miner(host))
|
||||||
|
else:
|
||||||
|
miner_ips_scan = await asyncio.gather(*scan_tasks)
|
||||||
|
miner_ips.extend(miner_ips_scan)
|
||||||
|
scan_tasks = []
|
||||||
miner_ips = list(filter(None, miner_ips))
|
miner_ips = list(filter(None, miner_ips))
|
||||||
print(f"Found {len(miner_ips)} connected miners...")
|
print(f"Found {len(miner_ips)} connected miners...")
|
||||||
create_miners_tasks = []
|
create_miners_tasks = []
|
||||||
@@ -47,7 +50,6 @@ class MinerNetwork:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def ping_miner(ip: ipaddress.ip_address) -> None or ipaddress.ip_address:
|
async def ping_miner(ip: ipaddress.ip_address) -> None or ipaddress.ip_address:
|
||||||
"""Send ping requests to a miner."""
|
|
||||||
for i in range(PING_RETRIES):
|
for i in range(PING_RETRIES):
|
||||||
connection_fut = asyncio.open_connection(str(ip), 4028)
|
connection_fut = asyncio.open_connection(str(ip), 4028)
|
||||||
try:
|
try:
|
||||||
@@ -64,7 +66,7 @@ class MinerNetwork:
|
|||||||
continue
|
continue
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
# handle for other connection errors
|
# handle for other connection errors
|
||||||
print("Unknown error...")
|
print(f"{str(ip)}: Connection Refused.")
|
||||||
# ping failed, likely with an exception
|
# ping failed, likely with an exception
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|||||||
7
settings.py
Normal file
7
settings.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
NETWORK_PING_RETRIES: int = 3
|
||||||
|
NETWORK_PING_TIMEOUT: int = 5
|
||||||
|
NETWORK_SCAN_THREADS: int = 100
|
||||||
|
|
||||||
|
CFG_UTIL_GET_VERSION_THREADS: int = 100
|
||||||
|
|
||||||
|
MINER_FACTORY_GET_VERSION_RETRIES: int = 3
|
||||||
Reference in New Issue
Block a user