-
Notifications
You must be signed in to change notification settings - Fork 314
Instead of sending a message to the index log when an indexing task finishes, stream results as they come in #1382
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
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import struct TSCBasic.ProcessResult | ||
|
||
/// The ID of a preparation or update indexstore task. This allows us to log messages from multiple concurrently running | ||
/// indexing tasks to the index log while still being able to differentiate them. | ||
public enum IndexTaskID: Sendable { | ||
case preparation(id: UInt32) | ||
case updateIndexStore(id: UInt32) | ||
|
||
private static func numberToEmojis(_ number: Int, numEmojis: Int) -> String { | ||
let emojis = ["🟥", "🟩", "🟦", "🟧", "⬜️", "🟪", "⬛️", "🟨", "🟫"] | ||
var number = abs(number) | ||
var result = "" | ||
for _ in 0..<numEmojis { | ||
let (quotient, remainder) = number.quotientAndRemainder(dividingBy: emojis.count) | ||
result += emojis[remainder] | ||
number = quotient | ||
} | ||
return result | ||
} | ||
|
||
/// Returns a two-character emoji string that allows easy differentiation between different task IDs. | ||
/// | ||
/// This marker is prepended to every line in the index log. | ||
public var emojiRepresentation: String { | ||
// Multiply by 2 and optionally add 1 to make sure preparation and update index store have distinct IDs. | ||
// Run .hashValue to make sure we semi-randomly pick new emoji markers for new tasks | ||
switch self { | ||
case .preparation(id: let id): | ||
return Self.numberToEmojis((id * 2).hashValue, numEmojis: 2) | ||
case .updateIndexStore(id: let id): | ||
return Self.numberToEmojis((id * 2 + 1).hashValue, numEmojis: 2) | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import Foundation | ||
|
||
/// Gathers data from a stdout or stderr pipe. When it has accumulated a full line, calls the handler to handle the | ||
/// string. | ||
public actor PipeAsStringHandler { | ||
/// Queue on which all data from the pipe will be handled. This allows us to have a | ||
/// nonisolated `handle` function but ensure that data gets processed in order. | ||
private let queue = AsyncQueue<Serial>() | ||
private var buffer = Data() | ||
|
||
/// The closure that actually handles | ||
private let handler: @Sendable (String) -> Void | ||
|
||
public init(handler: @escaping @Sendable (String) -> Void) { | ||
self.handler = handler | ||
} | ||
|
||
private func handleDataFromPipeImpl(_ newData: Data) { | ||
self.buffer += newData | ||
while let newlineIndex = self.buffer.firstIndex(of: UInt8(ascii: "\n")) { | ||
// Output a separate log message for every line in the pipe. | ||
// The reason why we don't output multiple lines in a single log message is that | ||
// a) os_log truncates log messages at about 1000 bytes. The assumption is that a single line is usually less | ||
// than 1000 bytes long but if we merge multiple lines into one message, we might easily exceed this limit. | ||
// b) It might be confusing why sometimes a single log message contains one line while sometimes it contains | ||
// multiple. | ||
handler(String(data: self.buffer[...newlineIndex], encoding: .utf8) ?? "<invalid UTF-8>") | ||
buffer = buffer[buffer.index(after: newlineIndex)...] | ||
} | ||
} | ||
|
||
public nonisolated func handleDataFromPipe(_ newData: Data) { | ||
queue.async { | ||
await self.handleDataFromPipeImpl(newData) | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Scanning the whole buffer every time doesn't seem ideal, but I guess lines aren't that long in practice?
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.
Yes, the expectation is that lines aren’t long and I can’t think of common scenarios where you get less than a full line from a pipe.