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

Convert Linux backends to use app log streaming #967

Merged
merged 6 commits into from
Nov 14, 2022

Conversation

freakboy3742
Copy link
Member

In order to support test mode (Refs #962), we need to convert app runners to use streamers, rather than just outputting logs directly to stdout. To make the code easier to review, I've split the introduction of streaming to the linux backends as a standalone PR, similar to what has been done with #966 for Android.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

Comment on lines 278 to 282
self.tools.subprocess.stream_output(
app.app_name,
log_popen,
stop_func=lambda: log_popen.poll() is not None,
)
Copy link
Member

Choose a reason for hiding this comment

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

curious....did you find the stop_func was necessary for log streaming to exit properly?

I'd expect checking poll() is functionally equivalent to the log streamer exiting when readline() returns an empty string....since that'll happen once the PIPE is closed...and that'll happen when the underlying process exits.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point - this was mostly done for consistency with the iOS/macOS/etc backends, but you're right - as we're streaming the actual process, and the actual process will exit, there's no need to poll here.

try:
# Start streaming logs for the app.
self.logger.info(
"Following log output (type CTRL-C to stop log)...",
Copy link
Member

Choose a reason for hiding this comment

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

This also appears to be adding back in the "send CTRL-C to exit" messages that were removed in #921.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh yeah - I forgot we made a conscious decision to pull those out.

Copy link
Member

@rmartin16 rmartin16 left a comment

Choose a reason for hiding this comment

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

In general, I think I have concerns about how much of work that's typically been encapsulated inside Subprocess is now being implemented in platform code.

More or less, this re-implements Subprocess._run_and_stream_output() in multiple places....but really _run_and_stream_output() is just an implementation of Subprocess.run().

Would it be possible to augment the Subprocess.run() signature to achieve the same outcome?

I've reviewed #962 and AFAICT, the primary goal is to monitor the output for sentinels. I think that would be achievable by exposing filter_func in Subprocess.run() (although, I think it should renamed since it isn't really filtering anything but we can bikeshed later).

All that said, macOS and iOS are fundamentally different since the App process and the process making the App output available are independent; so, they require a different architecture from the Linux backends here.

Let me know if I haven't taken in the whole picture properly.

@freakboy3742
Copy link
Member Author

Would it be possible to augment the Subprocess.run() signature to achieve the same outcome?

I've reviewed #962 and AFAICT, the primary goal is to monitor the output for sentinels. I think that would be achievable by exposing filter_func in Subprocess.run() (although, I think it should renamed since it isn't really filtering anything but we can bikeshed later).

All that said, macOS and iOS are fundamentally different since the App process and the process making the App output available are independent; so, they require a different architecture from the Linux backends here.

Let me know if I haven't taken in the whole picture properly.

You're not wrong - I've had very similar thoughts.

The only reason I didn't do it as part of this PR is that I wanted to confirm that the run sequence in fact was identical on every platform, and could be abstracted consistently, especially in the light of the changes we're going to need to make to stream filters for #962. As you note, macOS has a quite different approach; I wasn't 100% sure if we were going to end up with similar differences once we resolved the issues like the Android startup problem (#966) or Windows logging problem (#970).

Think of it as an incremental approach - get everything into a stream-based approach on a platform-by-platform basis (and fix some of the other log-related issues); then accomodate the testing changes; then refactor to pull out the common "streaming execution" code. Smaller focussed PRs tend to be easier to review.

Based on where I am right now, it seems very likely we'll be able to factor out some common code; the "run this app" code workflow is very similar across every platform. I'm not completely sure if it will just be adding a filter_func argument to run(), or a new method that encompasses a "testable execution", I should get a better feel for that once I've got testing working on a few platforms.

@freakboy3742 freakboy3742 merged commit 45584e5 into beeware:main Nov 14, 2022
@freakboy3742 freakboy3742 deleted the linux-streaming branch November 14, 2022 23:46
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.

3 participants