Skip to content

Updated SF-0007 to version 5 #1079

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

Merged
merged 2 commits into from
Dec 11, 2024

Conversation

iCharlesHu
Copy link
Contributor

This PR updates the proposal for SF-0007 Swift Subprocess to version 5 and added header docs. Here are the changes since version 3:

  • v4: Minor updates (primarily name changes):
    • Dropped the executing label from .run().
    • Removed references to Subprocess.AsyncBytes:
      • Instead, we use an opaque type: some AsyncSequence<UInt8, Error>.
      • When typed throws is ready, we can then update to the actual error type.
    • Updated .standardOutput and .standardError properties on Subprocess and CollectedResult to be non-optional (now they use fatalError instead).
      • Rationale: These properties can only be nil in two cases:
        1. The corresponding .output/.error was not set to .redirectToSequence when run() was called.
        2. These properties are accessed multiple times. This is because these AsyncSequences are reading pipes under the hood, and pipes can only be read once.
        • Both cases can’t be resolved until the source code is updated; they are therefore considered programming errors.
    • Updated StandardInputWriter to be non-sendable.
    • Renamed PlatformOptions.additionalAttributeConfigurator to Platform.preSpawnAttributeConfigurator; renamed PlatformOptions.additionalFileAttributeConfigurator to Platform.preSpawnFileAttributeConfigurator.
    • Updated all closeWhenDone parameter labels to closeAfterSpawningProcess.
    • Renamed Subprocess.Result to Subprocess.ExecutionResult.
    • Added Codable support to TerminationStatus and ExecutionResult.
    • Renamed TerminationStatus.exit:
      • From .exit to .exited.
      • From .wasUnhandledException to .isUnhandledException.
    • Added two sections under Future Direction: Support Launching Long Running Processes and Process Piping.
    • Added Linux-specific PlatformOptions: .closeAllUnknownFileDescriptors.
      • This option attempts to emulate Darwin’s POSIX_SPAWN_CLOEXEC_DEFAULT behavior. It is the default value on Darwin.
      • Unfortunately, posix_spawn does not support this flag natively, hence on Linux this behavior is opt-in, and we will fall back to a custom implementation of fork/exec.
  • v5: Platform-specific changes, Subprocess.runDetached, and others:
    • Added Hashable, CustomStringConvertable and CustomDebugStringConvertible conformance to Subprocess.Configuration and friends
    • Subprocess.Arguments:
      • Add an array initializer to Subprocess.Arguments:
        • public init(_ array: [String])
        • public init(_ array: [Data]).
    • Subprocess.CollectedOutputMethod:
      • Combined .collect and .collect(upTo:)
    • Subprocess.PlatformOptions (all platforms):
      • Changed from .default to using empty initializer .init().
      • Changed to prefer platform native types such as gid_t over Int.
    • Darwin Changes:
      • Updated PlatformOptions.createProcessGroup to PlatformOptions.processGroupID.
        • Also changed the public init.
      • Combined PlatformOptions.preSpawnAttributeConfigurator and PlatformOptions.preSpawnFileAttributeConfigurator into PlatformOptions.preSpawnProcessConfigurator to be consistant with other platforms.
    • Linux Changes:
      • Updated PlatformOptions for Linux.
      • Introduced PlatformOptions.preSpawnProcessConfigurator.
    • Windows Changes:
      • Removed Arguments first argument override and non-string support from Windows because Windows does not support either.
      • Introduced PlatformOptions for Windows.
      • Replaced Subprocess.send() with
        • Subprocess.terminate(withExitCode:)
        • Subprocess.suspend()
        • Subprocess.resume()
    • Subprocess.runDetached:
      • Introduced Subprocess.runDetached as a top level API and sibling to all Subprocess.run methods. This method allows you to spawn a subprocess WITHOUT needing to wait for it to finish.
    • Updated .standardOutput and .standardError properties on Subprocess to be AsyncSequence<Data, any Error> instead of AsyncSequence<UInt8, any Error>.
      • The previous design, while more "traditional", leads to performance problems when the subprocess outputs large amount of data
    • Teardown Sequence support (for Darwin and Linux):
      • Introduced Subprocess.teardown(using:) to allow developers to gracefully shutdown a subprocess.
      • Introuuced PlatformOptions.teardownSequence that will be used to gracefully shutdown the subprocess if the parent task is cancelled.

@iCharlesHu iCharlesHu added the proposal This PR is for a proposal label Dec 10, 2024
/// - output: A file descriptor to bind to the subprocess' standard output.
/// - error: A file descriptor to bind to the subprocess' standard error.
/// - Returns: the process identifier for the subprocess.
public static func runDetached(
Copy link
Member

Choose a reason for hiding this comment

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

Is this in the end just spawning an unstructured Task and calling run inside that task? If that's the case I would really prefer we don't offer that API and just expect users to construct that unstructured task themselves. This will allow them to still have some ownership of the task and cancel it if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No there is no unstructured task. This API is not async at all. It simply spawns the process and returns the PID to you as if you were calling posix_spawn yourself.

Copy link
Contributor

@itingliu itingliu left a comment

Choose a reason for hiding this comment

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

  • Please change the status (on line 6) to
* Status: **2nd Review, Active: Dec 12, 2024...Dec 19, 2024**

@itingliu
Copy link
Contributor

@swift-ci please test

@iCharlesHu
Copy link
Contributor Author

  • Please change the status (on line 6) to
* Status: **2nd Review, Active: Dec 12, 2024...Dec 19, 2024**

Updated! Thanks!

@iCharlesHu
Copy link
Contributor Author

@swift-ci please test

@itingliu itingliu merged commit 52ee324 into swiftlang:main Dec 11, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This PR is for a proposal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants