Skip to content

Commit bae6c94

Browse files
committed
Add timeout and error handlers
1 parent 1bb6044 commit bae6c94

File tree

3 files changed

+123
-124
lines changed

3 files changed

+123
-124
lines changed

manager/manager/launcher/launcher_gazebo.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,31 @@
44
from manager.manager.vnc.vnc_server import Vnc_server
55
from manager.libs.process_utils import (
66
wait_for_process_to_start,
7-
check_gpu_acceleration,
87
)
98
import subprocess
10-
import time
11-
import os
12-
import stat
139
from typing import List, Any
10+
from manager.ram_logging.log_manager import LogManager
1411

1512

1613
def call_service(service, service_type, request_data="{}"):
17-
command = f"ros2 service call {service} {service_type} '{request_data}'"
18-
subprocess.call(
19-
f"{command}",
20-
shell=True,
21-
stdout=sys.stdout,
22-
stderr=subprocess.STDOUT,
23-
bufsize=1024,
24-
universal_newlines=True,
25-
)
14+
command = f"sleep 10;ros2 service call {service} {service_type} '{request_data}'"
15+
try:
16+
p = subprocess.Popen(
17+
[
18+
f"{command}",
19+
],
20+
shell=True,
21+
stdout=sys.stdout,
22+
stderr=subprocess.STDOUT,
23+
bufsize=1024,
24+
universal_newlines=True,
25+
)
26+
p.wait(10)
27+
except subprocess.TimeoutExpired as e:
28+
p.kill()
29+
30+
LogManager.logger.exception(f"Unable to complete call: {service}")
31+
raise e
2632

2733

2834
class LauncherGazebo(ILauncher):

manager/manager/launcher/launcher_gzsim.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,45 @@
1616

1717
def call_gzservice(service, reqtype, reptype, timeout, req):
1818
command = f"gz service -s {service} --reqtype {reqtype} --reptype {reptype} --timeout {timeout} --req '{req}'"
19-
subprocess.call(
20-
f"{command}",
21-
shell=True,
22-
stdout=sys.stdout,
23-
stderr=subprocess.STDOUT,
24-
bufsize=1024,
25-
universal_newlines=True,
26-
)
19+
try:
20+
p = subprocess.Popen(
21+
[
22+
f"{command}",
23+
],
24+
shell=True,
25+
stdout=sys.stdout,
26+
stderr=subprocess.STDOUT,
27+
bufsize=1024,
28+
universal_newlines=True,
29+
)
30+
p.wait(10)
31+
except:
32+
p.kill()
33+
34+
LogManager.logger.exception(f"Unable to complete call: {service}")
35+
raise Exception(f"Unable to complete call: {service}")
2736

2837

2938
def call_service(service, service_type, request_data="{}"):
3039
command = f"ros2 service call {service} {service_type} '{request_data}'"
31-
subprocess.call(
32-
f"{command}",
33-
shell=True,
34-
stdout=sys.stdout,
35-
stderr=subprocess.STDOUT,
36-
bufsize=1024,
37-
universal_newlines=True,
38-
)
40+
try:
41+
p = subprocess.Popen(
42+
[
43+
f"{command}",
44+
],
45+
shell=True,
46+
stdout=sys.stdout,
47+
stderr=subprocess.STDOUT,
48+
bufsize=1024,
49+
universal_newlines=True,
50+
)
51+
p.wait(10)
52+
except:
53+
p.kill()
54+
55+
LogManager.logger.exception(f"Unable to complete call: {service}")
56+
raise Exception(f"Unable to complete call: {service}")
57+
3958

4059

4160
def is_ros_service_available(service_name):

manager/manager/manager.py

Lines changed: 69 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,27 @@ def on_prepare_tools(self, event):
406406
self.tools_launcher.run(self.consumer)
407407
LogManager.logger.info("Tools transition finished")
408408

409+
def write_to_tool_terminal(self, msg):
410+
"""Search console in docker different of /dev/pts/0 ."""
411+
pts_consoles = [
412+
f"/dev/pts/{dev}" for dev in os.listdir("/dev/pts/") if dev.isdigit()
413+
]
414+
consoles = []
415+
for console in pts_consoles:
416+
if console != "/dev/pts/0":
417+
try:
418+
# Search if it's a console
419+
with open(console, "w") as f:
420+
f.write("")
421+
consoles.append(console)
422+
except Exception:
423+
# Continue searching
424+
continue
425+
426+
for i in consoles:
427+
with open(i, "w") as console:
428+
console.write(msg)
429+
409430
def on_style_check_application(self, event):
410431
"""
411432
Handle the 'style_check' event.
@@ -421,27 +442,6 @@ def on_style_check_application(self, event):
421442
Raises:
422443
Exception: with the errors found in the linter
423444
"""
424-
425-
def find_docker_console():
426-
"""Search console in docker different of /dev/pts/0 ."""
427-
pts_consoles = [
428-
f"/dev/pts/{dev}" for dev in os.listdir("/dev/pts/") if dev.isdigit()
429-
]
430-
consoles = []
431-
for console in pts_consoles:
432-
if console != "/dev/pts/0":
433-
try:
434-
# Search if it's a console
435-
with open(console, "w") as f:
436-
f.write("")
437-
consoles.append(console)
438-
except Exception:
439-
# Continue searching
440-
continue
441-
442-
# raise Exception("No active console other than /dev/pts/0")
443-
return consoles
444-
445445
# Extract app config
446446
app_cfg = event.kwargs.get("data", {})
447447
try:
@@ -468,11 +468,7 @@ def find_docker_console():
468468
if errors == "":
469469
errors = "No errors found"
470470

471-
console_path = find_docker_console()
472-
for i in console_path:
473-
with open(i, "w") as console:
474-
console.write(errors + "\n\n")
475-
471+
self.write_to_tool_terminal(errors + "\n\n")
476472
raise Exception(errors)
477473

478474
def on_code_analysis(self, event):
@@ -633,27 +629,6 @@ def on_run_application(self, event):
633629
Parameters:
634630
event: The event object containing application configuration and code data.
635631
"""
636-
637-
def find_docker_console():
638-
"""Search console in docker different of /dev/pts/0 ."""
639-
pts_consoles = [
640-
f"/dev/pts/{dev}" for dev in os.listdir("/dev/pts/") if dev.isdigit()
641-
]
642-
consoles = []
643-
for console in pts_consoles:
644-
if console != "/dev/pts/0":
645-
try:
646-
# Search if it's a console
647-
with open(console, "w") as f:
648-
f.write("")
649-
consoles.append(console)
650-
except Exception:
651-
# Continue searching
652-
continue
653-
654-
# raise Exception("No active console other than /dev/pts/0")
655-
return consoles
656-
657632
# Kill already running code
658633
try:
659634
proc = psutil.Process(self.application_process.pid)
@@ -708,6 +683,7 @@ def find_docker_console():
708683
if returncode != 0:
709684
raise Exception("Failed to compile")
710685

686+
self.unpause_sim()
711687
self.application_process = subprocess.Popen(
712688
[
713689
"source /workspace/code/install/setup.bash && ros2 run academy academyCode"
@@ -720,7 +696,6 @@ def find_docker_console():
720696
shell=True,
721697
executable="/bin/bash",
722698
)
723-
self.unpause_sim()
724699
return
725700

726701
# Pass the linter
@@ -730,29 +705,23 @@ def find_docker_console():
730705
for error in errors:
731706
if error != "":
732707
failed_linter = True
733-
console_path = find_docker_console()
734-
for i in console_path:
735-
with open(i, "w") as console:
736-
console.write(error + "\n\n")
708+
self.write_to_tool_terminal(errors + "\n\n")
737709

738710
if failed_linter:
739711
raise Exception(errors)
740712

741-
try:
742-
fds = os.listdir("/dev/pts/")
743-
console_fd = str(max(map(int, fds[:-1])))
744-
745-
self.application_process = subprocess.Popen(
746-
["python3", entrypoint],
747-
stdin=open("/dev/pts/" + console_fd, "r"),
748-
stdout=sys.stdout,
749-
stderr=subprocess.STDOUT,
750-
bufsize=1024,
751-
universal_newlines=True,
752-
)
753-
self.unpause_sim()
754-
except:
755-
LogManager.logger.info("Run application failed")
713+
fds = os.listdir("/dev/pts/")
714+
console_fd = str(max(map(int, fds[:-1])))
715+
716+
self.unpause_sim()
717+
self.application_process = subprocess.Popen(
718+
["python3", entrypoint],
719+
stdin=open("/dev/pts/" + console_fd, "r"),
720+
stdout=sys.stdout,
721+
stderr=subprocess.STDOUT,
722+
bufsize=1024,
723+
universal_newlines=True,
724+
)
756725

757726
LogManager.logger.info("Run application transition finished")
758727

@@ -826,7 +795,6 @@ def on_disconnect(self, event):
826795
self.robot_launcher.terminate()
827796
except Exception as e:
828797
LogManager.logger.exception("Exception terminating robot launcher")
829-
830798
if self.world_launcher:
831799
try:
832800
self.world_launcher.terminate()
@@ -848,18 +816,15 @@ def process_message(self, message):
848816

849817
def on_pause(self, msg):
850818
if self.application_process is not None:
851-
try:
852-
proc = psutil.Process(self.application_process.pid)
853-
children = proc.children(recursive=True)
854-
children.append(proc)
855-
for p in children:
856-
try:
857-
p.suspend()
858-
except psutil.NoSuchProcess:
859-
pass
860-
self.pause_sim()
861-
except Exception as e:
862-
LogManager.logger.exception("Error suspending process")
819+
proc = psutil.Process(self.application_process.pid)
820+
children = proc.children(recursive=True)
821+
children.append(proc)
822+
for p in children:
823+
try:
824+
p.suspend()
825+
except psutil.NoSuchProcess:
826+
pass
827+
self.pause_sim()
863828
else:
864829
LogManager.logger.warning(
865830
"Application process was None during pause. Calling termination."
@@ -875,29 +840,34 @@ def on_resume(self, msg):
875840
msg: The event or message triggering the resume action.
876841
"""
877842
if self.application_process is not None:
878-
try:
879-
proc = psutil.Process(self.application_process.pid)
880-
children = proc.children(recursive=True)
881-
children.append(proc)
882-
for p in children:
883-
try:
884-
p.resume()
885-
except psutil.NoSuchProcess:
886-
pass
887-
self.unpause_sim()
888-
except Exception as e:
889-
LogManager.logger.exception("Error suspending process")
843+
proc = psutil.Process(self.application_process.pid)
844+
children = proc.children(recursive=True)
845+
children.append(proc)
846+
for p in children:
847+
try:
848+
p.resume()
849+
except psutil.NoSuchProcess:
850+
pass
851+
self.unpause_sim()
890852
else:
891853
LogManager.logger.warning(
892854
"Application process was None during resume. Calling termination."
893855
)
894856
self.reset_sim()
895857

896858
def pause_sim(self):
897-
self.tools_launcher.pause()
859+
try:
860+
self.tools_launcher.pause()
861+
except subprocess.TimeoutExpired as e:
862+
self.write_to_tool_terminal(f"{e}\n\n")
863+
raise Exception("Failed to pause simulator")
898864

899865
def unpause_sim(self):
900-
self.tools_launcher.unpause()
866+
try:
867+
self.tools_launcher.unpause()
868+
except subprocess.TimeoutExpired as e:
869+
self.write_to_tool_terminal(f"{e}\n\n")
870+
raise Exception("Failed to start simulator")
901871

902872
def reset_sim(self):
903873
"""
@@ -910,7 +880,11 @@ def reset_sim(self):
910880
if self.robot_launcher:
911881
self.robot_launcher.terminate()
912882

913-
self.tools_launcher.reset()
883+
try:
884+
self.tools_launcher.reset()
885+
except subprocess.TimeoutExpired as e:
886+
self.write_to_tool_terminal(f"{e}\n\n")
887+
raise Exception("Failed to reset simulator")
914888

915889
if self.robot_launcher:
916890
try:

0 commit comments

Comments
 (0)