Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent critical failure of audio services #2988

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions mycroft/audio/audioservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,28 +450,35 @@ def _queue(self, message):
self._play(message)

def _play(self, message):
"""
Handler for mycroft.audio.service.play. Starts playback of a
tracklist. Also determines if the user requested a special
service.
"""Start playback of a tracklist.

Args:
message: message bus message, not used but required
Also determines if the user requested a special service.
Handler for mycroft.audio.service.play

Args:
message: message bus message
"""
with self.service_lock:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @forslund mentioned, using this context manager means that exceptions thrown within this block will correctly release the lock. Better exception handling and logging good, but it's not actually addressing the reported issue.

More likely, there needs to be a timeout parameter (with a sane default) for the play methods that are calling out to separate services/processes. If the code blocks indefinitely on an external call, there's nothing to make this lock release short of a service restart.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the original issue was indeed vlc itself hanging forever and needing a restart, i wish it threw an exception 😅

tracks = message.data['tracks']
repeat = message.data.get('repeat', False)
# Find if the user wants to use a specific backend
for s in self.service:
if ('utterance' in message.data and
s.name in message.data['utterance']):
prefered_service = s
LOG.debug(s.name + ' would be prefered')
break
else:
prefered_service = None
self.play(tracks, prefered_service, repeat)
time.sleep(0.5)
preferred_service = None
for service in self.service:
try:
if ('utterance' in message.data and
service.name in message.data['utterance']):
preferred_service = service
LOG.debug(
f'{service.name} audioservice would be preferred')
break
except Exception:
LOG.error(
f'Failed to read audio service name: {service}')
try:
self.play(tracks, preferred_service, repeat)
time.sleep(0.5)
except Exception as e:
LOG.exception(e)

def _track_info(self, message):
"""
Expand Down