refactor: improve RPC handlers.
This commit is contained in:
@@ -597,7 +597,9 @@ class MinerProtocol(Protocol):
|
||||
ip=str(self.ip),
|
||||
make=self.make,
|
||||
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,
|
||||
hashboards=[
|
||||
HashBoard(slot=i, expected_chips=self.expected_chips)
|
||||
@@ -619,7 +621,7 @@ class BaseMiner(MinerProtocol):
|
||||
def __init__(self, ip: str) -> None:
|
||||
self.ip = ip
|
||||
|
||||
if self.expected_chips is None:
|
||||
if self.expected_chips is None and self.raw_model is not None:
|
||||
warnings.warn(
|
||||
f"Unknown chip count for miner type {self.raw_model}, "
|
||||
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.
|
||||
|
||||
"""
|
||||
while True:
|
||||
# make sure we can actually run each command, otherwise they will fail
|
||||
commands = self._check_commands(*commands)
|
||||
# standard multicommand format is "command1+command2"
|
||||
# standard format doesn't work for X19
|
||||
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):
|
||||
# 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 _send_split_multicommand
|
||||
command = "+".join(commands)
|
||||
try:
|
||||
data = await self.send_command(command, allow_warning=allow_warning)
|
||||
if "+" not in command:
|
||||
return {command: [data]}
|
||||
return data
|
||||
|
||||
except APIError:
|
||||
if "+" in command:
|
||||
return {command: [{}] for command in command.split("+")}
|
||||
return {command: [{}]}
|
||||
data = await self._send_split_multicommand(*commands)
|
||||
data["multicommand"] = True
|
||||
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
|
||||
def commands(self) -> list:
|
||||
|
||||
@@ -202,28 +202,33 @@ class BTMinerRPCAPI(BaseMinerRPCAPI):
|
||||
# standard multicommand format is "command1+command2"
|
||||
# commands starting with "get_" and the "status" command aren't supported, but we can fake that
|
||||
|
||||
tasks = []
|
||||
split_commands = []
|
||||
|
||||
for command in list(commands):
|
||||
if command.startswith("get_") or command == "status":
|
||||
commands.remove(command)
|
||||
# send seperately and append later
|
||||
tasks.append(
|
||||
asyncio.create_task(
|
||||
self._handle_multicommand(command, allow_warning=allow_warning)
|
||||
)
|
||||
)
|
||||
split_commands.append(command)
|
||||
|
||||
command = "+".join(commands)
|
||||
tasks.append(
|
||||
asyncio.create_task(
|
||||
self._handle_multicommand(command, allow_warning=allow_warning)
|
||||
|
||||
tasks = []
|
||||
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)
|
||||
|
||||
logging.debug(f"{self} - (Multicommand) - Received data")
|
||||
try:
|
||||
all_data = await asyncio.gather(*tasks)
|
||||
except APIError:
|
||||
return {}
|
||||
|
||||
data = {}
|
||||
for item in all_data:
|
||||
|
||||
@@ -36,36 +36,6 @@ class CGMinerRPCAPI(BaseMinerRPCAPI):
|
||||
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:
|
||||
"""Get miner version info.
|
||||
<details>
|
||||
|
||||
Reference in New Issue
Block a user