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

Allow processes to be started on start/stop of a session. #2138

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Chris3773
Copy link

@Chris3773 Chris3773 commented Feb 13, 2024

Description

Allows for processes to be started when a client connects, resumes an app or disconnects from an app.

Added new session envs.
SUNSHINE_CLIENT_ID - Not sure how useful this one is with how it's used right now.
SUNSHINE_CLIENT_UNIQUE_ID
SUNSHINE_CLIENT_SLOT - Can only be used when set to session.

I'm open to suggests for the header text for the config as I don't know if users will know what it means by Session.

Issues:

  • The envs SUNSHINE_APP_ID and SUNSHINE_APP_NAME can't be used when the process is set to session.
  • Output from the session process isn't logged.

Screenshot

image

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@CLAassistant
Copy link

CLAassistant commented Feb 13, 2024

CLA assistant check
All committers have signed the CLA.

@Chris3773 Chris3773 marked this pull request as draft February 13, 2024 03:01
@Chris3773 Chris3773 marked this pull request as ready for review February 13, 2024 03:18
@ReenigneArcher ReenigneArcher added this to the adjust lint rules milestone Feb 28, 2024
@Hazer
Copy link
Member

Hazer commented May 12, 2024

I have some points I'd like to discuss here:

  1. Given how sessions are used on the clients right now, this change feels confusing, because for the end-user, the session Starts once (process start and streaming start), and they can Resume (streaming start) or Quit it (streaming stop and process stop), and "Pausing/Getting out" the session (streaming stop) is kinda implicit, so the streaming session that starts and stops with each client connection, it's not so transparent to the user, at least in my point of view. Naming it per connection may make more sense, but I'm not so sure too.
  2. How does this should handle multiple connected clients to the same Application Session? Given I connect my tablet and resume the same session on my phone, both will run the same start command, and then both will run the stop? Only the first connected client should run the starting commands and the last connected should run the stop commands? If it's the former, can you point out some use cases for me so I can test the behavior?
  3. I think we should split Command preparations in the UI in 2 sections, "Per-Application", "Per-Client/Device" instead of using the Run on session checkbox to differentiate, this may avoid the session confusion, and allows to have a proper Title and Subtitle describing each usage and expected behavior.

Comment on lines +9 to +10
#include <boost/process.hpp>

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is needed

Comment on lines +26 to +27
boost::process::environment env;

Copy link
Member

Choose a reason for hiding this comment

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

This seems unused, remove?

Comment on lines +1844 to +1868
std::error_code ec;
std::vector<cmd_t>::const_iterator prep_it = std::end(config::sunshine.prep_cmds);
for (; prep_it != std::begin(config::sunshine.prep_cmds); --prep_it) {
auto &cmd = *(prep_it - 1);

// Skip empty and non session commands
if (cmd.undo_cmd.empty() || !cmd.on_session) {
continue;
}

boost::filesystem::path working_dir = find_working_directory(cmd.do_cmd);
BOOST_LOG(info) << "Executing Undo Cmd: ["sv << cmd.undo_cmd << ']';
auto child = platf::run_command(cmd.elevated, true, cmd.undo_cmd, working_dir, session.env, nullptr, ec, nullptr);

if (ec) {
BOOST_LOG(warning) << "Couldn't run ["sv << cmd.undo_cmd << "]: "sv << ec.message();
}

child.wait();
auto ret = child.exit_code();

if (ret != 0) {
BOOST_LOG(warning) << '[' << cmd.undo_cmd << "] failed with code ["sv << ret << ']';
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This files looks awfully big already and this feels out of place, can we move this to another file, maybe reuse some of it in process too?

I'd suggest moving this to something like: user_commands::run_session_stop() and call it here

Comment on lines +1921 to +1946
std::error_code ec;
std::vector<cmd_t>::const_iterator prep_it = std::begin(config::sunshine.prep_cmds);
for (; prep_it != std::end(config::sunshine.prep_cmds); ++prep_it) {
auto &cmd = *prep_it;

// Skip empty and non session commands
if (cmd.do_cmd.empty() || !cmd.on_session) {
continue;
}

boost::filesystem::path working_dir = find_working_directory(cmd.do_cmd);
BOOST_LOG(info) << "Executing Do Cmd: ["sv << cmd.do_cmd << ']';
auto child = platf::run_command(cmd.elevated, true, cmd.do_cmd, working_dir, session.env, nullptr, ec, nullptr);

if (ec) {
BOOST_LOG(error) << "Couldn't run ["sv << cmd.do_cmd << "]: System: "sv << ec.message();
return -1;
}

child.wait();
auto ret = child.exit_code();
if (ret != 0) {
BOOST_LOG(error) << '[' << cmd.do_cmd << "] failed with code ["sv << ret << ']';
return -1;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest moving this to something like: user_commands::run_session_start() and call it here

Comment on lines +1804 to +1833
boost::filesystem::path
find_working_directory(const std::string &cmd) {
// Parse the raw command string into parts to get the actual command portion
#ifdef _WIN32
auto parts = boost::program_options::split_winmain(cmd);
#else
auto parts = boost::program_options::split_unix(cmd);
#endif
if (parts.empty()) {
BOOST_LOG(error) << "Unable to parse command: "sv << cmd;
return boost::filesystem::path();
}

BOOST_LOG(debug) << "Parsed executable ["sv << parts.at(0) << "] from command ["sv << cmd << ']';

// If the cmd path is not an absolute path, resolve it using our PATH variable
boost::filesystem::path cmd_path(parts.at(0));
if (!cmd_path.is_absolute()) {
cmd_path = boost::process::search_path(parts.at(0));
if (cmd_path.empty()) {
BOOST_LOG(error) << "Unable to find executable ["sv << parts.at(0) << "]. Is it in your PATH?"sv;
return boost::filesystem::path();
}
}

BOOST_LOG(debug) << "Resolved executable ["sv << parts.at(0) << "] to path ["sv << cmd_path << ']';

// Now that we have a complete path, we can just use parent_path()
return cmd_path.parent_path();
}
Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest moving this to user_commands

@@ -109,7 +109,7 @@ namespace proc {
}

boost::filesystem::path
find_working_directory(const std::string &cmd, bp::environment &env) {
find_working_directory(const std::string &cmd) {
Copy link
Member

Choose a reason for hiding this comment

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

Can this be merged with the other method with the same name?

Copy link
Member

Choose a reason for hiding this comment

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

Can this be moved to the same user_commands if something like this gets created?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants