refactor: improve RPC handlers.
This commit is contained in:
@@ -597,7 +597,9 @@ class MinerProtocol(Protocol):
|
|||||||
ip=str(self.ip),
|
ip=str(self.ip),
|
||||||
make=self.make,
|
make=self.make,
|
||||||
model=self.model,
|
model=self.model,
|
||||||
expected_chips=self.expected_chips * self.expected_hashboards,
|
expected_chips=self.expected_chips
|
||||||
|
if self.expected_chips is not None
|
||||||
|
else 0 * self.expected_hashboards,
|
||||||
expected_hashboards=self.expected_hashboards,
|
expected_hashboards=self.expected_hashboards,
|
||||||
hashboards=[
|
hashboards=[
|
||||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||||
@@ -619,7 +621,7 @@ class BaseMiner(MinerProtocol):
|
|||||||
def __init__(self, ip: str) -> None:
|
def __init__(self, ip: str) -> None:
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|
||||||
if self.expected_chips is None:
|
if self.expected_chips is None and self.raw_model is not None:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
f"Unknown chip count for miner type {self.raw_model}, "
|
f"Unknown chip count for miner type {self.raw_model}, "
|
||||||
f"please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
|
f"please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
|
||||||
|
|||||||
@@ -110,38 +110,41 @@ class BaseMinerRPCAPI:
|
|||||||
allow_warning: A boolean to supress APIWarnings.
|
allow_warning: A boolean to supress APIWarnings.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
while True:
|
# make sure we can actually run each command, otherwise they will fail
|
||||||
# make sure we can actually run each command, otherwise they will fail
|
commands = self._check_commands(*commands)
|
||||||
commands = self._check_commands(*commands)
|
# standard multicommand format is "command1+command2"
|
||||||
# standard multicommand format is "command1+command2"
|
# doesn't work for S19 which uses the backup _send_split_multicommand
|
||||||
# standard format doesn't work for X19
|
command = "+".join(commands)
|
||||||
command = "+".join(commands)
|
|
||||||
try:
|
|
||||||
data = await self.send_command(command, allow_warning=allow_warning)
|
|
||||||
except APIError as e:
|
|
||||||
# try to identify the error
|
|
||||||
if e.message is not None:
|
|
||||||
if ":" in e.message:
|
|
||||||
err_command = e.message.split(":")[0]
|
|
||||||
if err_command in commands:
|
|
||||||
commands.remove(err_command)
|
|
||||||
continue
|
|
||||||
return {command: [{}] for command in commands}
|
|
||||||
logging.debug(f"{self} - (Multicommand) - Received data")
|
|
||||||
data["multicommand"] = True
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def _handle_multicommand(self, command: str, allow_warning: bool = True):
|
|
||||||
try:
|
try:
|
||||||
data = await self.send_command(command, allow_warning=allow_warning)
|
data = await self.send_command(command, allow_warning=allow_warning)
|
||||||
if "+" not in command:
|
|
||||||
return {command: [data]}
|
|
||||||
return data
|
|
||||||
|
|
||||||
except APIError:
|
except APIError:
|
||||||
if "+" in command:
|
data = await self._send_split_multicommand(*commands)
|
||||||
return {command: [{}] for command in command.split("+")}
|
data["multicommand"] = True
|
||||||
return {command: [{}]}
|
return data
|
||||||
|
|
||||||
|
async def _send_split_multicommand(
|
||||||
|
self, *commands, allow_warning: bool = True
|
||||||
|
) -> dict:
|
||||||
|
tasks = {}
|
||||||
|
# send all commands individually
|
||||||
|
for cmd in commands:
|
||||||
|
tasks[cmd] = asyncio.create_task(
|
||||||
|
self.send_command(cmd, allow_warning=allow_warning)
|
||||||
|
)
|
||||||
|
|
||||||
|
await asyncio.gather(*[tasks[cmd] for cmd in tasks], return_exceptions=True)
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
for cmd in tasks:
|
||||||
|
try:
|
||||||
|
result = tasks[cmd].result()
|
||||||
|
if result is None or result == {}:
|
||||||
|
result = {}
|
||||||
|
data[cmd] = [result]
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def commands(self) -> list:
|
def commands(self) -> list:
|
||||||
|
|||||||
@@ -202,28 +202,33 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
# standard multicommand format is "command1+command2"
|
# standard multicommand format is "command1+command2"
|
||||||
# commands starting with "get_" and the "status" command aren't supported, but we can fake that
|
# commands starting with "get_" and the "status" command aren't supported, but we can fake that
|
||||||
|
|
||||||
tasks = []
|
split_commands = []
|
||||||
|
|
||||||
for command in list(commands):
|
for command in list(commands):
|
||||||
if command.startswith("get_") or command == "status":
|
if command.startswith("get_") or command == "status":
|
||||||
commands.remove(command)
|
commands.remove(command)
|
||||||
# send seperately and append later
|
# send seperately and append later
|
||||||
tasks.append(
|
split_commands.append(command)
|
||||||
asyncio.create_task(
|
|
||||||
self._handle_multicommand(command, allow_warning=allow_warning)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
command = "+".join(commands)
|
command = "+".join(commands)
|
||||||
tasks.append(
|
|
||||||
asyncio.create_task(
|
tasks = []
|
||||||
self._handle_multicommand(command, allow_warning=allow_warning)
|
if len(split_commands) > 0:
|
||||||
|
tasks.append(
|
||||||
|
asyncio.create_task(
|
||||||
|
self._send_split_multicommand(
|
||||||
|
*split_commands, allow_warning=allow_warning
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
tasks.append(
|
||||||
|
asyncio.create_task(self.send_command(command, allow_warning=allow_warning))
|
||||||
)
|
)
|
||||||
|
|
||||||
all_data = await asyncio.gather(*tasks)
|
try:
|
||||||
|
all_data = await asyncio.gather(*tasks)
|
||||||
logging.debug(f"{self} - (Multicommand) - Received data")
|
except APIError:
|
||||||
|
return {}
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
for item in all_data:
|
for item in all_data:
|
||||||
|
|||||||
@@ -36,36 +36,6 @@ class CGMinerRPCAPI(BaseMinerRPCAPI):
|
|||||||
ip: The IP of the miner to reference the API on.
|
ip: The IP of the miner to reference the API on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def multicommand(self, *commands: str, allow_warning: bool = True) -> dict:
|
|
||||||
# make sure we can actually run each command, otherwise they will fail
|
|
||||||
commands = self._check_commands(*commands)
|
|
||||||
# standard multicommand format is "command1+command2"
|
|
||||||
# doesn't work for S19 which uses the backup _x19_multicommand
|
|
||||||
command = "+".join(commands)
|
|
||||||
try:
|
|
||||||
data = await self.send_command(command, allow_warning=allow_warning)
|
|
||||||
except APIError:
|
|
||||||
logging.debug(f"{self} - (Multicommand) - Handling X19 multicommand.")
|
|
||||||
data = await self._x19_multicommand(*command.split("+"))
|
|
||||||
data["multicommand"] = True
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def _x19_multicommand(self, *commands) -> dict:
|
|
||||||
tasks = []
|
|
||||||
# send all commands individually
|
|
||||||
for cmd in commands:
|
|
||||||
tasks.append(
|
|
||||||
asyncio.create_task(self._handle_multicommand(cmd, allow_warning=True))
|
|
||||||
)
|
|
||||||
|
|
||||||
all_data = await asyncio.gather(*tasks)
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
for item in all_data:
|
|
||||||
data.update(item)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def version(self) -> dict:
|
async def version(self) -> dict:
|
||||||
"""Get miner version info.
|
"""Get miner version info.
|
||||||
<details>
|
<details>
|
||||||
|
|||||||
Reference in New Issue
Block a user