Skip to content

Commit

Permalink
fix: Raise error when aexpect_helper doesn't work properly
Browse files Browse the repository at this point in the history
When aexpect_helper does not work properly, the process will hang
without any log information. This fix adds a timeout and checks the
process status and raises an error if the process terminates
prematurely.

Signed-off-by: Yihuang Yu <[email protected]>
  • Loading branch information
PaulYuuu committed Aug 2, 2024
1 parent 4e5ac96 commit 49179fa
Showing 1 changed file with 32 additions and 18 deletions.
50 changes: 32 additions & 18 deletions aexpect/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,8 @@ def __init__(self, command=None, a_id=None, auto_close=False, echo=False,
# Start the server (which runs the command)
if command:
helper_cmd = utils_path.find_command('aexpect_helper')
self._aexpect_helper = subprocess.Popen([helper_cmd], # pylint: disable=R1732
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
pass_fds=pass_fds)
sub = self._aexpect_helper
# Send parameters to the server
sub.stdin.write(f"{self.a_id}\n".encode(self.encoding))
sub.stdin.write(f"{echo}\n".encode(self.encoding))
readers = ",".join(self.readers)
sub.stdin.write(f"{readers}\n".encode(self.encoding))
sub.stdin.write(f"{command}\n".encode(self.encoding))
sub.stdin.flush()
# Wait for the server to complete its initialization
while (f"Server {self.a_id} ready" not in
sub.stdout.readline().decode(self.encoding, "ignore")):
pass
self._aexpect_helper = self._get_aexpect_helper(
helper_cmd, pass_fds, echo, command)

# Open the reading pipes
if is_file_locked(self.lock_server_running_filename):
Expand Down Expand Up @@ -232,6 +216,36 @@ def __del__(self):
if self.auto_close:
self.close()

def _get_aexpect_helper(self, helper_cmd, pass_fds, echo, command):
sub = subprocess.Popen([helper_cmd], # pylint: disable=R1732
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
pass_fds=pass_fds)
# Send parameters to the server
sub.stdin.write(f"{self.a_id}\n".encode(self.encoding))
sub.stdin.write(f"{echo}\n".encode(self.encoding))
readers = ",".join(self.readers)
sub.stdin.write(f"{readers}\n".encode(self.encoding))
sub.stdin.write(f"{command}\n".encode(self.encoding))
sub.stdin.flush()
# Wait for the server to complete its initialization
full_output = ""
pattern = f"Server {self.a_id} ready"
end_time = time.time() + 60
while time.time() < end_time:
output = sub.stdout.readline().decode(self.encoding, "ignore")
if pattern in output:
break
full_output += output
sub_status = sub.poll()
if sub_status is not None:
raise ExpectProcessTerminatedError(pattern, sub_status, full_output)
else:
raise ExpectTimeoutError(pattern, full_output)
return sub

def _add_reader(self, reader):
"""
Add a reader whose file descriptor can be obtained with _get_fd().
Expand Down

0 comments on commit 49179fa

Please sign in to comment.