-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import some parts of LLBSupport from swift-llbuild2
- Loading branch information
Showing
19 changed files
with
1,242 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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,7 @@ | ||
.DS_Store | ||
/.build | ||
/Packages | ||
/*.xcodeproj | ||
xcuserdata/ | ||
DerivedData/ | ||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata |
This file contains 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,55 @@ | ||
# Code of Conduct | ||
To be a truly great community, Swift.org needs to welcome developers from all walks of life, | ||
with different backgrounds, and with a wide range of experience. A diverse and friendly | ||
community will have more great ideas, more unique perspectives, and produce more great | ||
code. We will work diligently to make the Swift community welcoming to everyone. | ||
|
||
To give clarity of what is expected of our members, Swift.org has adopted the code of conduct | ||
defined by [contributor-covenant.org](https://www.contributor-covenant.org). This document is used across many open source | ||
communities, and we think it articulates our values well. The full text is copied below: | ||
|
||
### Contributor Code of Conduct v1.3 | ||
As contributors and maintainers of this project, and in the interest of fostering an open and | ||
welcoming community, we pledge to respect all people who contribute through reporting | ||
issues, posting feature requests, updating documentation, submitting pull requests or patches, | ||
and other activities. | ||
|
||
We are committed to making participation in this project a harassment-free experience for | ||
everyone, regardless of level of experience, gender, gender identity and expression, sexual | ||
orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or | ||
nationality. | ||
|
||
Examples of unacceptable behavior by participants include: | ||
- The use of sexualized language or imagery | ||
- Personal attacks | ||
- Trolling or insulting/derogatory comments | ||
- Public or private harassment | ||
- Publishing other’s private information, such as physical or electronic addresses, without explicit permission | ||
- Other unethical or unprofessional conduct | ||
|
||
Project maintainers have the right and responsibility to remove, edit, or reject comments, | ||
commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of | ||
Conduct, or to ban temporarily or permanently any contributor for other behaviors that they | ||
deem inappropriate, threatening, offensive, or harmful. | ||
|
||
By adopting this Code of Conduct, project maintainers commit themselves to fairly and | ||
consistently applying these principles to every aspect of managing this project. Project | ||
maintainers who do not follow or enforce the Code of Conduct may be permanently removed | ||
from the project team. | ||
|
||
This code of conduct applies both within project spaces and in public spaces when an | ||
individual is representing the project or its community. | ||
|
||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by | ||
contacting a project maintainer at [conduct@swift.org](mailto:conduct@swift.org). All complaints will be reviewed and | ||
investigated and will result in a response that is deemed necessary and appropriate to the | ||
circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter | ||
of an incident. | ||
|
||
*This policy is adapted from the Contributor Code of Conduct [version 1.3.0](http://contributor-covenant.org/version/1/3/0/).* | ||
|
||
### Reporting | ||
A working group of community members is committed to promptly addressing any [reported | ||
issues](mailto:conduct@swift.org). Working group members are volunteers appointed by the project lead, with a | ||
preference for individuals with varied backgrounds and perspectives. Membership is expected | ||
to change regularly, and may grow or shrink. |
This file contains 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,10 @@ | ||
By submitting a pull request, you represent that you have the right to license | ||
your contribution to Apple and the community, and agree by submitting the patch | ||
that your contributions are licensed under the [Swift | ||
license](https://swift.org/LICENSE.txt). | ||
|
||
--- | ||
|
||
Before submitting the pull request, please make sure you have tested your | ||
changes and that they follow the Swift project [guidelines for contributing | ||
code](https://swift.org/contributing/#contributing-code). |
This file contains 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,16 @@ | ||
{ | ||
"object": { | ||
"pins": [ | ||
{ | ||
"package": "swift-nio", | ||
"repositoryURL": "https://github.com/apple/swift-nio.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "120acb15c39aa3217e9888e515de160378fbcc1e", | ||
"version": "2.18.0" | ||
} | ||
} | ||
] | ||
}, | ||
"version": 1 | ||
} |
This file contains 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,22 @@ | ||
// swift-tools-version:5.1 | ||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "swift-tools-support-async", | ||
products: [ | ||
.library( | ||
name: "TSFUtility", | ||
targets: ["TSFUtility"]), | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.8.0"), | ||
], | ||
targets: [ | ||
.target( | ||
name: "TSFUtility", | ||
dependencies: [ | ||
"NIO", | ||
] | ||
), | ||
] | ||
) |
This file contains 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 |
---|---|---|
@@ -1 +1,12 @@ | ||
# swift-tools-support-async | ||
# swift-tools-support-async | ||
|
||
Common infrastructural helpers on top of NIO for [llbuild2](https://github.com/apple/swift-llbuild2) and [swiftpm-on-llbuild2](https://github.com/apple/swiftpm-on-llbuild2) projects. This is **NOT** a general purpose package and is unlikely to ever become stable. | ||
|
||
## License | ||
|
||
Copyright (c) 2020 Apple Inc. and the Swift project authors. | ||
Licensed under Apache License v2.0 with Runtime Library Exception. | ||
|
||
See http://swift.org/LICENSE.txt for license information. | ||
|
||
See http://swift.org/CONTRIBUTORS.txt for Swift project authors. |
This file contains 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,22 @@ | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See http://swift.org/LICENSE.txt for license information | ||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
|
||
|
||
extension Array { | ||
/// Make several slices out of a given array. | ||
/// - Returns: | ||
/// An array of slices of `maxStride` elements each. | ||
@inlinable | ||
public func llbSliceBy(maxStride: Int) -> [ArraySlice<Element>] { | ||
let elementsCount = self.count | ||
let groupsCount = (elementsCount + maxStride - 1) / maxStride | ||
return (0..<groupsCount).map({ n in | ||
self[n*maxStride..<Swift.min(elementsCount, (n+1)*maxStride)] | ||
}) | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
Sources/TSFUtility/Futures/BatchingFutureOperationQueue.swift
This file contains 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,95 @@ | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See http://swift.org/LICENSE.txt for license information | ||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
|
||
import Foundation | ||
|
||
|
||
/// Run the given computations on a given array in batches, exercising | ||
/// a specified amount of parallelism. | ||
/// | ||
/// - Discussion: | ||
/// For some blocking operations (such as file system accesses) executing | ||
/// them on the NIO loops is very expensive since it blocks the event | ||
/// processing machinery. Here we use extra threads for such operations. | ||
public struct LLBBatchingFutureOperationQueue { | ||
|
||
/// Threads capable of running futures. | ||
public let group: LLBFuturesDispatchGroup | ||
|
||
/// Queue of outstanding operations. | ||
@usableFromInline | ||
let operationQueue: OperationQueue | ||
|
||
/// Maximum number of operations executed concurrently. | ||
public let maxOpCount: Int | ||
|
||
/// Return the number of operations currently queued. | ||
@inlinable | ||
public var opCount: Int { | ||
return operationQueue.operationCount | ||
} | ||
|
||
/// Whether the queue is suspended. | ||
@inlinable | ||
public var isSuspended: Bool { | ||
return operationQueue.isSuspended | ||
} | ||
|
||
/// | ||
/// - Parameters: | ||
/// - name: Unique string label, for logging. | ||
/// - group: Threads capable of running futures. | ||
/// - maxConcurrentOperationCount: | ||
/// Operations to execute in parallel. | ||
@inlinable | ||
public init(name: String, group: LLBFuturesDispatchGroup, maxConcurrentOperationCount maxOpCount: Int, qualityOfService: QualityOfService = .default) { | ||
self.group = group | ||
self.maxOpCount = maxOpCount | ||
self.operationQueue = OperationQueue(llbWithName: name, maxConcurrentOperationCount: maxOpCount) | ||
self.operationQueue.qualityOfService = qualityOfService | ||
} | ||
|
||
@inlinable | ||
public func execute<T>(_ body: @escaping () throws -> T) -> LLBFuture<T> { | ||
let promise = group.next().makePromise(of: T.self) | ||
operationQueue.addOperation { | ||
promise.fulfill(body) | ||
} | ||
return promise.futureResult | ||
} | ||
|
||
@inlinable | ||
public func execute<T>(_ body: @escaping () -> LLBFuture<T>) -> LLBFuture<T> { | ||
let promise = group.next().makePromise(of: T.self) | ||
operationQueue.addOperation { | ||
let f = body() | ||
f.cascade(to: promise) | ||
|
||
// Wait for completion, to ensure we maintain at most N concurrent operations. | ||
_ = try? f.wait() | ||
} | ||
return promise.futureResult | ||
} | ||
|
||
/// Order-preserving parallel execution. Wait for everything to complete. | ||
@inlinable | ||
public func execute<A,T>(_ args: [A], minStride: Int = 1, _ body: @escaping (ArraySlice<A>) throws -> [T]) -> LLBFuture<[T]> { | ||
let futures: [LLBFuture<[T]>] = executeNoWait(args, minStride: minStride, body) | ||
let loop = futures.first?.eventLoop ?? group.next() | ||
return LLBFuture<[T]>.whenAllSucceed(futures, on: loop).map{$0.flatMap{$0}} | ||
} | ||
|
||
/// Order-preserving parallel execution. | ||
/// Do not wait for all executions to complete, returning individual futures. | ||
@inlinable | ||
public func executeNoWait<A,T>(_ args: [A], minStride: Int = 1, maxStride: Int = Int.max, _ body: @escaping (ArraySlice<A>) throws -> [T]) -> [LLBFuture<[T]>] { | ||
let batches: [ArraySlice<A>] = args.llbSliceBy(maxStride: max(minStride, min(maxStride, args.count / maxOpCount))) | ||
return batches.map{arg in execute{try body(arg)}} | ||
} | ||
|
||
} |
This file contains 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,56 @@ | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See http://swift.org/LICENSE.txt for license information | ||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
|
||
|
||
/// A construct which expresses operations which can be asynchronously | ||
/// cancelled. The cancellation is not guaranteed and no ordering guarantees | ||
/// are provided with respect to the order of future's callbacks and the | ||
/// cancel operation returning. | ||
public struct LLBCancellableFuture<T>: LLBCancelProtocol { | ||
/// The underlying future. | ||
public let future: LLBFuture<T> | ||
|
||
/// The way to asynchronously cancel the operation backing up the future. | ||
public let canceller: LLBCanceller | ||
|
||
/// Initialize the future with a given canceller. | ||
public init(_ future: LLBFuture<T>, canceller specificCanceller: LLBCanceller? = nil) { | ||
self.future = future | ||
let canceller = specificCanceller ?? LLBCanceller() | ||
self.canceller = canceller | ||
self.future.whenComplete { _ in | ||
// Do not invoke the cancel handler if the future | ||
// has already terminated. This is a bit opportunistic | ||
// and can miss some cancellation invocations, but | ||
// we expect the cancellation handlers to be no-op | ||
// when cancelling something that's not there. | ||
canceller.abandon() | ||
} | ||
} | ||
|
||
/// Initialize with a given handler which can be | ||
/// subsequently invoked through self.canceller.cancel() | ||
public init(_ future: LLBFuture<T>, handler: LLBCancelProtocol) { | ||
self = LLBCancellableFuture(future, canceller: LLBCanceller(handler)) | ||
} | ||
|
||
/// Conformance to the `CancelProtocol`. | ||
public func cancel(reason: String?) { | ||
canceller.cancel(reason: reason) | ||
} | ||
} | ||
|
||
|
||
/// Some surface compatibility with EventLoopFuture to minimize | ||
/// the amount of code change in tests and other places. | ||
extension LLBCancellableFuture { | ||
@inlinable | ||
public func wait() throws -> T { | ||
try future.wait() | ||
} | ||
} |
Oops, something went wrong.