-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Support required nodes Currently, the only way to specify that a given node is required for a given `LaunchDescription` is to register an `OnProcessExit` handler for the exit event of the required node that then emits a `Shutdown` event. Instead of requiring this boilerplate for a common use-case, add an `on_exit` parameter to `ExecuteProcess` that can take actions, and add a new action called `Shutdown` that immediately causes the launched system to shut down. This allows for the concept of a required node to be expressed simply with: launch_ros.actions.Node( # ... on_exit=Shutdown() ) Resolve #174 Signed-off-by: Kyle Fazzari <kyle@canonical.com> * Inherit from EmitEvent Signed-off-by: Kyle Fazzari <kyle@canonical.com> * Properly align type Signed-off-by: Kyle Fazzari <kyle@canonical.com> * Expose reason Signed-off-by: Kyle Fazzari <kyle@canonical.com>
- Loading branch information
Showing
5 changed files
with
139 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Copyright 2019 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Module for the Shutdown action.""" | ||
|
||
import logging | ||
from typing import Text | ||
|
||
from .emit_event import EmitEvent | ||
from ..events import Shutdown as ShutdownEvent | ||
from ..events.process import ProcessExited | ||
from ..launch_context import LaunchContext | ||
|
||
_logger = logging.getLogger(name='launch') | ||
|
||
|
||
class Shutdown(EmitEvent): | ||
"""Action that shuts down a launched system by emitting Shutdown when executed.""" | ||
|
||
def __init__(self, *, reason: Text = 'reason not given', **kwargs): | ||
super().__init__(event=ShutdownEvent(reason=reason), **kwargs) | ||
|
||
def execute(self, context: LaunchContext): | ||
"""Execute the action.""" | ||
try: | ||
event = context.locals.event | ||
except AttributeError: | ||
event = None | ||
|
||
if isinstance(event, ProcessExited): | ||
_logger.info('process[{}] was required: shutting down launched system'.format( | ||
event.process_name)) | ||
|
||
super().execute(context) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Copyright 2019 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Tests for the Shutdown action class.""" | ||
|
||
from launch import LaunchContext | ||
from launch.actions import Shutdown | ||
from launch.conditions import IfCondition | ||
from launch.events import Shutdown as ShutdownEvent | ||
|
||
|
||
def test_shutdown_execute(): | ||
"""Test the execute (or visit) of the Shutdown class.""" | ||
action = Shutdown() | ||
context = LaunchContext() | ||
assert context._event_queue.qsize() == 0 | ||
assert action.visit(context) is None | ||
assert context._event_queue.qsize() == 1 | ||
event = context._event_queue.get_nowait() | ||
assert isinstance(event, ShutdownEvent) | ||
|
||
|
||
def test_shutdown_execute_conditional(): | ||
"""Test the conditional execution (or visit) of the Shutdown class.""" | ||
true_action = Shutdown(condition=IfCondition('True')) | ||
false_action = Shutdown(condition=IfCondition('False')) | ||
context = LaunchContext() | ||
|
||
assert context._event_queue.qsize() == 0 | ||
assert false_action.visit(context) is None | ||
assert context._event_queue.qsize() == 0 | ||
assert true_action.visit(context) is None | ||
assert context._event_queue.qsize() == 1 | ||
event = context._event_queue.get_nowait() | ||
assert isinstance(event, ShutdownEvent) | ||
|
||
|
||
def test_shutdown_reason(): | ||
"""Test the execute (or visit) of a Shutdown class that has a reason.""" | ||
action = Shutdown(reason='test reason') | ||
context = LaunchContext() | ||
assert action.visit(context) is None | ||
assert context._event_queue.qsize() == 1 | ||
event = context._event_queue.get_nowait() | ||
assert isinstance(event, ShutdownEvent) | ||
assert event.reason == 'test reason' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters