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

[launch] consider refactoring ExecuteProcess into Execute and Executable #114

Open
wjwwood opened this issue Jul 12, 2018 · 7 comments
Open
Labels
backlog enhancement New feature or request
Milestone

Comments

@wjwwood
Copy link
Member

wjwwood commented Jul 12, 2018

I believe it might be wise to separate the description of a process to be executed and its state while running from the Action which executes it.

Currently all of this information is encapsulated in the ExecuteProcess action, and my proposal would be to replace that with an action called Execute that takes an Executable (not an action or launch description entity, just a new kind of class). The Executable would contain any information needed by Execute to actually execute the executable described or introspect it. There could be sub classes of both Execute and Executable. For instance, a sub class of Executable might be Node or LifecycleNode, and a sub class of Execute might be ExecuteRemotely (execute on a different machine).

The reasons for doing this include:

  • using Executables (or subclasses thereof) with other actions
  • cleaner abstractions
    • i.e. the ExecuteProcess class is really big now and it would be nice to break into smaller parts
  • more readable
    • e.g. Execute(Executable(...)) or Execute(Node(...)) rather than ExecuteProcess(...) and Node(...)

The first reason is the most impactful, because it allows for a few use cases that aren't currently easy to implement:

  • Collect or generate Executable instances and later decide whether to pass to Execute, ExecuteRemotely, or ExecuteInDocker (just ideas)
  • Pass ComponentNode (possibly a subclass of Executable which represents a node that can be loaded dynamically) to either Execute() or ExecuteNodesInSharedProcess() (name needs work)
    • where the latter would take several ComponentNode instances and run them all in a single process

I still have some design questions in mind, like:

  • should Node inherit from Executable
  • should Executable contain process related things like pid and produce events for stdout and process exit, etc...
    • or should there be a Process that also inherits from Executable
    • because Node might not be associated with a process, or rather a process might not be associated with a single Node
  • what is the contract between Executable and Execute?
    • which creates event handlers and stores information?
    • what exactly are the responsibilities of Execute?
@ivanpauno
Copy link
Member

I thought a little bit about this, and about how it would look in the new frontends (examples only in XML here).

I would have the following classes:

  • A Node class, that describes a node (name, namespace, remappings, parameters).
    • A ComposableNode class.
    • A LifecycleNode class.
  • An Executable class (or Process class), that describes an executable (with process information).
    • A SingleNodeExecutable class that describes an executable that runs only one node. It may also inherit from Node, or take a Node in its constructor (is an implementation detail).
    • A MultiNodeExecutable, which inherits from node and takes a list of Node in its constructor.
  • An abstract BaseExecute action.
    • An Execute action.
      • An ExecuteContainer action. It should take both a Node, that is the container, and a list of ComposableNode as arguments.
    • We could have ExecuteRemotely, ExecuteInDocker, etc.

For XML (or other frontend), I think we should check the parent entity and behave differently according to that.
e.g.:

<node ATTRIBUTES_FOR_EXECUTION_EXECUTABLE_AND_NODE_DESCRIPTION/>
<execute_remotely ATTRIBUTES_FOR EXECUTION>
  <node ATTRIBUTES_FOR_EXECUTABLE_AND_NODE_DESCRIPTION/>
  <multi_node ATTRIBUTES_FOR_EXECUTABLE>
    <node ATTRIBUTES_FOR_DESCRIBING_A_NODE/>
    <node ATTRIBUTES_FOR_DESCRIBING_A_NODE/>
  </multi_node>
</execute_remotely>

So in each case the tag may accept different attributes, but it would be less verbose.

@roger-strain
Copy link
Contributor

I've been working with the guys who are putting together ideas for Multi-machine launching (ros2/design#255), and wanted to follow up on some of the feedback there. I saw the mention of this issue, and I'd like to see if we can help on getting some of this work done, and figure out how to use this concept for our remote execution needs. Also want to make sure we don't start running with ideas that have been obsoleted by other changes. There are good notes above from both @wjwwood and @ivanpauno; does everything here still feel current?

Also, there's discussion in the FP about some changes to how things would be called, for instance:

e.g. Execute(Executable(...)) or Execute(Node(...)) rather than ExecuteProcess(...) and Node(...)

Are there any concerns about breaking changes and backward compatibility in this area?

@ivanpauno
Copy link
Member

Are there any concerns about breaking changes and backward compatibility in this area?

Yes. It should be done in a backwards compatible way. i.e.: The ExecuteProcess class, etc, should still exist, making use of the new objects to avoid duplicated code, and print a deprecated warning when an user uses it.

I think that everything previously commented here still stands.
I think that a good start would be to propose an API, and share it for review.
In general, my idea is to separate descriptions from "Execute" actions. We've already done that in some cases (like here), but we haven't applied that consistently.

If you need any extra input for the design of the API, please let me know and I will try to help.

@roger-strain
Copy link
Contributor

@ivanpauno Finally had some time to dig into this and learn quite a bit more about how things are structured. I'm not sure if this is in quite the format you were wanting, but we've put together some thoughts about how to approach this. I've created a document in a fork of the design repo, but I'm not sure the document itself needs to be pulled there. Just needed a place to park some thoughts.

Take a look to see if things are on the right track; if you'd like me to move this somewhere else, I certainly can.

Also, (and this is probably a little premature) assuming we eventually get to the point of implementing the refactor, can you point me to the appropriate unit tests so I can make sure to update them/add new ones as appropriate?

ExecuteProcess Refactor discussion

@ivanpauno
Copy link
Member

@roger-strain Thanks for working on this!

I had a quick look, here some comments:

  • Probably, launch_ros.descriptions.ComposableNode can't inherit from launch_ros.descriptions.Node, as it doesn't have for example a node_executable argument. Maybe both can inherit from a common base class, that doesn't specify either plugin name nor executable name. Maybe, we don't need a base class at all.
  • About the apply_context idea. I think that probably people would want to have both kind of substitutions, e.g.: for some things check an environment variable locally, from some others check an environment variable in the remote computer. I would rather have another set of substitutions for the ones that have to be executed in the remote computer, e.g.: launch.substitutions.remote.EnvironmentVariableSubstitution. We could add some magic to infer the connection_description if the Substitution is composed in a ExecuteSshProcess action, to avoid duplication (I have a mental idea of how to do that).

I think that before continuing the discussion, it would be good to open a PR in ros2/design.
It will have more visibility there, and it's also better for receiving feedback (making comments right after the place it applies is nicer).

@roger-strain
Copy link
Contributor

@ivanpauno Is the document naming/formatting okay for a PR as is? I can go set that up now if it looks like it's in good enough format for that discussion.

@ros-discourse
Copy link

This issue has been mentioned on ROS Discourse. There might be relevant details there:

https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2020-07-16/15468/1

roger-strain pushed a commit to roger-strain/launch that referenced this issue Aug 19, 2020
Part of implementation of refactor for ros2#114

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>
roger-strain pushed a commit to roger-strain/launch that referenced this issue Jan 25, 2021
Part of implementation of refactor for ros2#114

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>
mlanting pushed a commit to roger-strain/launch that referenced this issue Sep 30, 2021
Part of implementation of refactor for ros2#114

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>
mlanting pushed a commit to roger-strain/launch that referenced this issue Sep 30, 2021
Part of implementation of refactor for ros2#114

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>
mlanting pushed a commit to roger-strain/launch that referenced this issue Oct 28, 2021
Part of implementation of refactor for ros2#114

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>
hidmic pushed a commit that referenced this issue Oct 29, 2021
* Adding Executable description class

Part of implementation of refactor for #114

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>

* Cleaned up access to substituted values

Modified handling of cmd parameter as described in #263

Distro A; OPSEC #2893

Signed-off-by: Roger Strain <rstrain@swri.org>

* Initial implementation of execute_local

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Fixed minor bugs to verify unit tests

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Unit test fixes

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Adjust for launch_ros modifications, add unit tests

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Apply minor updates to address feedback

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Refactor arguments to apply to executable

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Fix order of parameters

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Fixed default log name prefix

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Fix unit tests

Distro A; OPSEC #4584

Signed-off-by: Roger Strain <rstrain@swri.org>

* Removed some language from file headers

Distro A, OPSEC #4584. You may have additional rights; please see https://rosmilitary.org/faq/?category=ros-2-license

Signed-off-by: matthew.lanting <mlanting@dcscorp.com>

* Add prefix filtering to Executable description class.

Distro A, OPSEC #4584. You may have additional rights; please see https://rosmilitary.org/faq/?category=ros-2-license

Signed-off-by: matthew.lanting <mlanting@dcscorp.com>

* Formatting fixes.

Distro A, OPSEC #4584. You may have additional rights; please see https://rosmilitary.org/faq/?category=ros-2-license

Signed-off-by: matthew.lanting <mlanting@dcscorp.com>

* Fixed indentation in descriptions/executable.py.

Distro A, OPSEC #4584. You may have additional rights; please see https://rosmilitary.org/faq/?category=ros-2-license

Signed-off-by: matthew.lanting <mlanting@dcscorp.com>

* Fixed namechange missed during rebase.

Distro A, OPSEC #4584. You may have additional rights; please see https://rosmilitary.org/faq/?category=ros-2-license

Signed-off-by: matthew.lanting <mlanting@dcscorp.com>

Co-authored-by: Roger Strain <rstrain@swri.org>
Co-authored-by: matthew.lanting <mlanting@dcscorp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants