-
Notifications
You must be signed in to change notification settings - Fork 28
Allow callers to run a subprocess and provide low and high water marks when using SequenceOutput to emit standard output and standard error as soon as it arrives. #40
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
7324ac4
7b6899c
9b173ab
ab43ae4
10aa523
aa903ad
bb57bf2
955e9c9
5f2df5f
4bac06a
ae0de61
d65f2ce
c8fe778
4de3d79
30876f5
ff7ae12
48b97f2
d94a9c6
888666b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -210,8 +210,15 @@ public struct BytesOutput: OutputProtocol { | |
#endif | ||
public struct SequenceOutput: OutputProtocol { | ||
public typealias OutputType = Void | ||
|
||
internal init() {} | ||
internal let lowWater: Int? | ||
internal let highWater: Int? | ||
internal let bufferSize: Int | ||
|
||
internal init(lowWater: Int? = nil, highWater: Int? = nil, bufferSize: Int = readBufferSize) { | ||
self.lowWater = lowWater | ||
self.highWater = highWater | ||
self.bufferSize = bufferSize | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t think it’s appropriate to include these parameters here for a couple of reasons:
Considering all this, I suggest we move these parameters to Darwin’s specific There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noted. I'll look into moving these parameters. |
||
} | ||
|
||
#if SubprocessSpan | ||
|
@@ -284,6 +291,9 @@ extension OutputProtocol where Self == SequenceOutput { | |
/// to the `.standardOutput` (or `.standardError`) property | ||
/// of `Execution` as `AsyncSequence<Data>`. | ||
public static var sequence: Self { .init() } | ||
public static func sequence(lowWater: Int? = nil, highWater: Int? = nil, bufferSize: Int? = nil) -> Self { | ||
.init(lowWater: lowWater, highWater: highWater, bufferSize: bufferSize ?? readBufferSize) | ||
} | ||
} | ||
|
||
// MARK: - Span Default Implementations | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -665,6 +665,44 @@ extension SubprocessUnixTests { | |
#expect(catResult.terminationStatus.isSuccess) | ||
#expect(catResult.standardError == expected) | ||
} | ||
|
||
@Test func testSlowDripRedirectedOutputRedirectToSequence() async throws { | ||
let threshold: Double = 0.5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately in tests you'll have to write
In the beginning to work around the same availability issue. See other tests for examples. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @iCharlesHu When I first started working on this, I was very confused as to why some of the tests weren't running my new code and it was because of this check. Wouldn't it be better to have them skipped and noted as such in the test output rather than falsely succeeding? I'm thinking something like this:
Of course, we can have a helper function to make this less verbose. Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @iCharlesHu I went ahead and conditionalized this one test this way as an example. Let me know if you don't like that and would like me to revert to a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rdingman unfortunately this won't work because on Swift 6.2 and above the compiler will complain the code inside of Unfortunately so far this is the only way I found that works. Very ugly... but it'll have to do for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @iCharlesHu Hmm. This builds just fine for me with the latest Swift 6.2 toolchain, has the intended results, and works with the currently shipping Swift 6.1 toolchain. However, I'll go ahead and revert this and match the existing tests. |
||
|
||
let script = """ | ||
echo "DONE" | ||
sleep \(threshold) | ||
""" | ||
|
||
let start = ContinuousClock().now | ||
|
||
let catResult = try await Subprocess.run( | ||
.path("/bin/bash"), | ||
arguments: ["-c", script], | ||
output: .sequence(lowWater: 0), | ||
error: .discarded, | ||
body: { (execution, _) in | ||
for try await chunk in execution.standardOutput { | ||
let string = chunk.withUnsafeBytes { String(decoding: $0, as: UTF8.self) } | ||
|
||
if string.hasPrefix("DONE") { | ||
let end = ContinuousClock().now | ||
|
||
if (end - start) > .seconds(threshold) { | ||
return "Failure" | ||
|
||
} else { | ||
return "Success" | ||
} | ||
} | ||
} | ||
|
||
return "Failure" | ||
} | ||
) | ||
#expect(catResult.terminationStatus.isSuccess) | ||
#expect(catResult.value == "Success") | ||
} | ||
} | ||
|
||
// MARK: - PlatformOption Tests | ||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AsyncBufferSequence
is a shared type across all platforms therefore we can't unconditionally refer to platform specific typedispatchIO
here. We may see Windows build failure as a resultThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback. I'll look into implementing this in such a way that platforms without dispatchIO don't break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.