Skip to content

Commit

Permalink
Merge pull request #25 from BrianPugh/infinite-retry
Browse files Browse the repository at this point in the history
Infinitely attempt to reconnect if attempts is set to a negative number
  • Loading branch information
BrianPugh authored Sep 8, 2022
2 parents d63aca7 + 22391e3 commit 0fc0f6a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
18 changes: 12 additions & 6 deletions belay/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
SpecialFunctionNameError,
)
from .inspect import getsource
from .pyboard import Pyboard, PyboardException
from .pyboard import Pyboard, PyboardError, PyboardException
from .webrepl import WebreplToSerial

# Typing
Expand Down Expand Up @@ -531,26 +531,32 @@ def sync(
progress_update(description="Cleaning up...")
self._exec_snippet("sync_end")

def close(self):
def close(self) -> None:
"""Close the connection to device."""
return self._board.close()

def reconnect(self, attempts: Optional[int] = None):
def reconnect(self, attempts: Optional[int] = None) -> None:
"""Reconnect to the device and replay the command history.
Parameters
----------
attempts : int
Number of times to attempt to connect to board with a 1 second delay in-between.
If ``None``, defaults to whatever value was supplied to init (1).
If ``None``, defaults to whatever value was supplied to init.
If init value is 0, then defaults to 1.
"""
if len(self._cmd_history) == self.MAX_CMD_HISTORY_LEN:
raise MaxHistoryLengthError

kwargs = self._board_kwargs.copy()
kwargs["attempts"] = self.attempts if attempts is None else attempts
kwargs["attempts"] = attempts
if kwargs["attempts"] is None:
kwargs["attempts"] = self.attempts if self.attempts else 1

self._connect_to_board(**kwargs)
try:
self._connect_to_board(**kwargs)
except PyboardError as e:
raise ConnectionLost from e

# Playback the history
for cmd in self._cmd_history:
Expand Down
41 changes: 28 additions & 13 deletions belay/pyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"""

import ast
import itertools
import os
import sys
import time
Expand Down Expand Up @@ -267,19 +268,32 @@ def inWaiting(self):
class Pyboard:
def __init__(
self,
device,
baudrate=115200,
user="micro",
password="python",
attempts=1,
exclusive=True,
device: str,
baudrate: int = 115200,
user: str = "micro",
password: str = "python",
attempts: int = 1,
exclusive: bool = True,
):
"""
Parameters
----------
wait: int
(N-1) of attempts to try and connect
device: str
Some device specificier like ``'/dev/ttyACM0'`` or ``'192.168.1.1'``.
baudrate: int
If a serial-like connection, this baudrate will be used.
user: str
If connection requires a username, this will be used.
password: str
If connection requires a password, this will be used.
attempts: int
Number of attempts to try and connect to board.
If a ``<0`` value is provided, will infinitely try to connect.
exclusive: bool
If a serial-like connection, this configures the ``exclusive`` flag.
"""
if attempts == 0:
raise ValueError('"attempts" cannot be 0.')
self.in_raw_repl = False
self.use_raw_paste = True
if device.startswith("exec:"):
Expand All @@ -304,16 +318,17 @@ def __init__(
if serial.__version__ >= "3.3":
serial_kwargs["exclusive"] = exclusive

for _ in range(attempts):
for attempt_count in itertools.count(start=1):
try:
self.serial = serial.Serial(device, **serial_kwargs)
break
except (OSError, IOError): # Py2 and Py3 have different errors
if attempts == 1:
continue
pass

if attempt_count == attempts:
raise PyboardError("failed to access " + device)

time.sleep(1.0)
else:
raise PyboardError("failed to access " + device)

def close(self):
self.serial.close()
Expand Down
1 change: 1 addition & 0 deletions docs/source/Connections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Example:
device = Device("/dev/ttyUSB0", attempts=10)
By default, ``attempts=0``, meaning that Belay will **not** attempt to reconnect with the device.
If ``attempts`` is set to a negative value, Belay will infinitely attempt to reconnect with the device.
If using a serial connection, a serial device __might__ not be assigned to the name upon reconnecting.
See the `UDev Rules`_ section for ways to ensure the same name is assigned upon reconnection.

Expand Down

0 comments on commit 0fc0f6a

Please sign in to comment.