Skip to content

Commit

Permalink
Improve read_byte retry mechanism #8
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenbe committed May 7, 2024
1 parent 11c66dc commit a7eff0a
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
10 changes: 8 additions & 2 deletions comfospot40/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import copy
from datetime import datetime
from serial import SerialException
import asyncio


class Parser:
Expand All @@ -19,12 +20,17 @@ def __init__(self, serial, packetlog=None, state=State()):
def get_state(self):
return self._state

async def read_byte(self):
async def read_byte(self, retries=5):
while True:
try:
return await self._ser.read(1)
except SerialException as e:
logging.warn("Failed to read serial", e)
logging.warning("Failed to read serial: {}".format(e))
if retries > 0:
await asyncio.sleep(0.1 * retries)
retries -= 1
else:
raise e

async def search_length(self, data):
logging.info("z")
Expand Down
55 changes: 55 additions & 0 deletions tests/parser_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import asyncio
import unittest
import comfospot40
import logging
from serial import SerialException


class TestStateLoad(unittest.IsolatedAsyncioTestCase):
async def test_read_byte_ok(self):
class TestSerial:
async def read(self, _):
return b"A"

s = TestSerial()
p = comfospot40.Parser(s)
self.assertEqual(b"A", await p.read_byte())

async def test_read_byte_error(self):
logging.disable(logging.CRITICAL)

class TestSerial:
async def read(self, _):
raise SerialException("something")
return b"A"

s = TestSerial()
p = comfospot40.Parser(s)
with self.assertRaises(SerialException):
await p.read_byte(0)

async def test_read_byte_retry(self):
logging.disable(logging.CRITICAL)

class TestSerial:
async def read(self, _):
raise SerialException("something")
return b"A"

s = TestSerial()
p = comfospot40.Parser(s)
with self.assertRaises(SerialException):
await asyncio.wait_for(p.read_byte(0), timeout=1)

async def test_read_byte_retry_timeout(self):
logging.disable(logging.CRITICAL)

class TestSerial:
async def read(self, _):
raise SerialException("something")
return b"A"

s = TestSerial()
p = comfospot40.Parser(s)
with self.assertRaises(asyncio.exceptions.TimeoutError):
await asyncio.wait_for(p.read_byte(2), timeout=0.1)

0 comments on commit a7eff0a

Please sign in to comment.