Refactor PIO Home IDE RPC

This commit is contained in:
Ivan Kravets
2021-11-05 12:57:09 +02:00
parent 9040bbb75a
commit 4a9a478243

View File

@ -20,33 +20,63 @@ from platformio.compat import aio_get_running_loop
class IDERPC:
COMMAND_TIMEOUT = 1.5 # in seconds
def __init__(self):
self._cmd_queue = []
self._result_queue = {}
self._ide_queue = []
self._cmd_queue = {}
async def listen_commands(self):
self._cmd_queue.append(aio_get_running_loop().create_future())
return await self._cmd_queue[-1]
f = aio_get_running_loop().create_future()
self._ide_queue.append(f)
self._process_commands()
return await f
async def send_command(self, command, params=None):
if not self._cmd_queue:
raise JSONRPC20DispatchException(
code=4005, message="PIO Home IDE agent is not started"
)
cmd_id = None
while self._cmd_queue:
cmd_id = f"ide-{command}-{time.time()}"
self._cmd_queue.pop().set_result(
{
"id": cmd_id,
"method": command,
"params": params,
}
)
if not cmd_id:
return
self._result_queue[cmd_id] = aio_get_running_loop().create_future()
return await self._result_queue[cmd_id]
cmd_id = f"ide-{command}-{time.time()}"
self._cmd_queue[cmd_id] = {
"method": command,
"params": params,
"time": time.time(),
"future": aio_get_running_loop().create_future(),
}
self._process_commands()
# in case if IDE agent has not been started
aio_get_running_loop().call_later(
self.COMMAND_TIMEOUT + 0.1, self._process_commands
)
return await self._cmd_queue[cmd_id]["future"]
def on_command_result(self, cmd_id, value):
self._result_queue[cmd_id].set_result(value)
if cmd_id not in self._cmd_queue:
return
self._cmd_queue[cmd_id]["future"].set_result(value)
del self._cmd_queue[cmd_id]
def _process_commands(self):
for cmd_id in list(self._cmd_queue):
cmd_data = self._cmd_queue[cmd_id]
if cmd_data["future"].done():
del self._cmd_queue[cmd_id]
continue
if (
not self._ide_queue
and (time.time() - cmd_data["time"]) > self.COMMAND_TIMEOUT
):
cmd_data["future"].set_exception(
JSONRPC20DispatchException(
code=4005, message="PIO Home IDE agent is not started"
)
)
continue
while self._ide_queue:
self._ide_queue.pop().set_result(
{
"id": cmd_id,
"method": cmd_data["method"],
"params": cmd_data["params"],
}
)