Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
f924c43
prepare typedThrow
pbk20191 May 30, 2024
3ed1069
Merge remote-tracking branch 'refs/remotes/origin/develop'
pbk20191 May 31, 2024
bfa0b13
adapt `fullTypedThrow`
pbk20191 May 31, 2024
cfd1e5d
implement custom isolation check
pbk20191 May 31, 2024
0d4a1cf
Merge remote-tracking branch 'refs/remotes/origin/develop'
pbk20191 Jun 1, 2024
8131b43
make properties private
pbk20191 Jun 1, 2024
c2fb0d0
Merge remote-tracking branch 'refs/remotes/origin/develop'
pbk20191 Jun 4, 2024
01e39cc
fix typedThrow compile issue
pbk20191 Jun 4, 2024
e7e8987
inline error conversion
pbk20191 Jun 4, 2024
58b389b
Merge remote-tracking branch 'refs/remotes/origin/master'
pbk20191 Jun 5, 2024
6e644cd
fix errors for swift 6
pbk20191 Jun 6, 2024
d9878ad
Combine&Concurrency: reimplement subscription model to fix internal b…
pbk20191 Jun 6, 2024
ee8468c
Combine & Concurrency: introduce asyncflatmap
pbk20191 Jun 7, 2024
686a892
fix test fail
pbk20191 Jun 7, 2024
7fbe6ff
change implementation to fix rare crash in test
pbk20191 Jun 7, 2024
30be947
Merge branch 'develop' into feature/swift6
pbk20191 Jun 7, 2024
42a0f21
Merge branch 'develop' into feature/swift6
pbk20191 Jun 7, 2024
d15e723
CoreData: interit Exeuctor attribute to make scheduledTaskType valid
pbk20191 Jun 7, 2024
6ea4d4d
Merge branch 'develop' into feature/swift6
pbk20191 Jun 7, 2024
1841e58
remove unused module import declaration
pbk20191 Jun 7, 2024
ab17557
suppress sendable warning in dedicated case
pbk20191 Jun 8, 2024
6977f08
suppress sendable warning on dedicated case
pbk20191 Jun 8, 2024
006f284
fix async iterator isolation
pbk20191 Jun 8, 2024
5b46411
Concurrency: suppress sendable warning on dedicated case
pbk20191 Jun 9, 2024
54c3762
AsyncFlatMap: fix test fail on precise demand, Notification: fix comp…
pbk20191 Jun 10, 2024
24d54b9
remove unwanted schema
pbk20191 Jun 10, 2024
77960fa
AsyncFlatMap: fix task leak and propagate cancellation to upstream pr…
pbk20191 Jun 10, 2024
f3c69be
Merge branch 'develop' into feature/swift6
pbk20191 Jun 10, 2024
8075e9d
Concurrency: mark support for isolation
pbk20191 Jun 10, 2024
aee8c09
CompatAsyncPublisher: fix compiler crash by assertion
pbk20191 Jun 10, 2024
7f58409
mapTask, TryMapTask: enqueue to separate task to prevent transformer…
pbk20191 Jun 10, 2024
9f15f94
Merge branch 'develop' into feature/swift6
pbk20191 Jun 10, 2024
18fbd5c
swift 6: fix compile fail
pbk20191 Jun 11, 2024
19664dc
ensure subscription deinitializer is called outside of lock
pbk20191 Jun 11, 2024
9d15737
Merge branch 'develop' into feature/swift6
pbk20191 Jun 11, 2024
4487005
AsyncFlatMap: adapting dedicated typedThrow
pbk20191 Jun 11, 2024
5ae5fa7
AsyncFlatMap: changing genernal protocol for better type conformance …
pbk20191 Jun 11, 2024
78b1932
fix DiscardingTaskGroup simulation stops too early.
pbk20191 Jun 17, 2024
a8c3e39
Merge remote-tracking branch 'refs/remotes/origin/develop'
pbk20191 Jun 17, 2024
2351dfd
fix discardingTaskgroup simulation ends too early
pbk20191 Jun 17, 2024
13d0a48
refine keep alive Taskgroup to use actor state
pbk20191 Jun 17, 2024
7f0b99b
Backport DiscardingTaskGroup: wrap defer stack with do block for imme…
pbk20191 Jun 17, 2024
507bffd
MultiMapTask: add downstreamLock to match reactive stream spec
pbk20191 Jun 21, 2024
39bb3b8
MapTasks: add locks to match Reactivestream spec on Subscriptions
pbk20191 Jun 21, 2024
1ce755c
Merge remote-tracking branch 'refs/remotes/origin/develop'
pbk20191 Jun 21, 2024
0edafc9
moving to swift 6, using package acces modifier.
pbk20191 Jun 26, 2024
124caf8
commit to test for library use case
pbk20191 Jun 27, 2024
9d018b5
Update README.md
pbk20191 Jun 28, 2024
404281d
add TaskLocal test failing case for request about issue
pbk20191 Jun 29, 2024
4e17f2d
Merge commit '9d018b535a1542270711e201ec80f76a629ad17f' into feature/…
pbk20191 Jun 29, 2024
632ae77
implement Serial Priority based RunLoopExecutor Source
pbk20191 Jul 5, 2024
d0b4e52
implement qos elevation of PriorityRunLoop. remove legacy runloop sch…
pbk20191 Jul 6, 2024
a54923b
compact qos algorithnm
pbk20191 Jul 6, 2024
4e8910a
fix available annotation
pbk20191 Jul 8, 2024
a2dde3c
Swift 6 Concurrency check 임시 대응
pbk20191 Jul 15, 2024
2b20d80
update readme and implment PruneMemory which clean up memory footprints
pbk20191 Jul 15, 2024
8a46f77
adpat new typedThrow syntax and refactor simulating DiscardTaskGroup
pbk20191 Jul 17, 2024
0fb2d87
resolve for swift6
pbk20191 Dec 19, 2024
1fc4ef1
fix test failure
pbk20191 Dec 19, 2024
f8b5c23
backport CoreDataContext perform method
pbk20191 Dec 21, 2024
8faf2ff
expose generic Error for coreData
pbk20191 Dec 21, 2024
a125334
hide wip executor class
pbk20191 Dec 21, 2024
cb4800e
refactor backport discardingTask
pbk20191 Dec 21, 2024
32073f6
disable PruneMemory feature in non-Objective-C platform
pbk20191 Dec 21, 2024
3ea51ab
ensure isolation for backport discardingTask usecase
pbk20191 Dec 21, 2024
c60b47f
refactor for concurrency checking
pbk20191 Jan 2, 2025
bc0ddb9
add isolation parameter
pbk20191 Jan 5, 2025
271ed0a
spawn child task for receive(subscription:) callback
pbk20191 Jan 6, 2025
e83bb22
adapt Swift Testing for some test case
pbk20191 Jan 26, 2025
f8d202d
implement moody::camel::ConcurrentQueue based RunLoop SerialExecutor
pbk20191 Jan 27, 2025
62ef0bb
migrate some test to Swift-Testing
pbk20191 Jan 28, 2025
8f68ec4
update RunLoopExecutor
pbk20191 Jan 30, 2025
d4fc8b9
update UnfairLock with new api
pbk20191 Feb 11, 2026
65b4a29
implementing new RunLoopExecutor
pbk20191 Feb 18, 2026
3cd5f99
Add TetraRunLoopConcurrency kqueue run-loop executor (iOS 13)
pbk20191 Jul 6, 2026
3180e74
Align KQScheduler drain/timer protocol with the reference engine
pbk20191 Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/Tetra.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "TetraRunLoopConcurrencyTests"
BuildableName = "TetraRunLoopConcurrencyTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
33 changes: 33 additions & 0 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

131 changes: 124 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.9
// swift-tools-version: 6.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -18,28 +18,145 @@ let package = Package(
.library(
name: "Tetra",
targets: ["Tetra"]
)
),
],
// Opt-in trait for the SchedulingExecutor / RunLoopExecutor / MainExecutor SPI
// conformances in `TetraRunLoopConcurrency`. Those protocols are only nameable on a
// toolchain whose stdlib exposes them (a development snapshot); the release/standard
// stdlib does not (`cannot find type 'SchedulingExecutor'`), and no `#if compiler(>=x)`
// can tell the two apart. NOT in the default set → OFF by default, so release/standard
// toolchains build cleanly. Enable with `swift build --traits SchedulingExecutorSPI` on
// a toolchain that exposes the SPI; an enabled trait becomes the `#if SchedulingExecutorSPI`
// compilation condition.
traits: [
.trait(
name: "SchedulingExecutorSPI",
description: "Conform StackBoundRunLoopExecutor to the SchedulingExecutor/RunLoopExecutor/MainExecutor _Concurrency SPI protocols (only compilable where the stdlib exposes them)."
),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(
url: "https://github.com/apple/swift-collections.git",
.upToNextMajor(from: "1.3.0"),
traits: [
.defaults,
// .trait(name: "UnstableContainersPreview")
],
),
.package(
url: "https://github.com/apple/swift-atomics.git",
.upToNextMajor(from: "1.3.0"),
traits: [.defaults],
),
.package(url: "https://github.com/apple/swift-async-algorithms", from: "1.1.5"),

],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "Namespace",
swiftSettings: [
.swiftLanguageMode(.v6)
]
),
.target(
name: "NamespaceExtension",
dependencies: [
"Namespace",
],
swiftSettings: [
.swiftLanguageMode(.v6)
]
),
.target(
name: "CriticalSection",
dependencies: [
.product(name: "Atomics", package: "swift-atomics"),

],
swiftSettings: [
.swiftLanguageMode(.v6),
.enableExperimentalFeature("StaticExclusiveOnly"),
.enableExperimentalFeature("RawLayout"),
.enableExperimentalFeature("BuiltinModule"),
.enableExperimentalFeature("Lifetimes"),
.enableExperimentalFeature("LifetimeDependence"),
]
),
.target(
name: "BackportDiscardingTaskGroup",
dependencies: [
"Namespace",
"CriticalSection",
],
swiftSettings: [
.enableUpcomingFeature("FullTypedThrows"),
.enableExperimentalFeature("IsolatedAny"),
.swiftLanguageMode(.v6)
]
),
.target(
name: "Tetra",
dependencies: [],
dependencies: [
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "HeapModule", package: "swift-collections"),

"BackPortAsyncSequence",
"CriticalSection",
"BackportDiscardingTaskGroup",
"Namespace",
"NamespaceExtension", "TetraRunLoopConcurrency",
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
],
swiftSettings: [
.enableUpcomingFeature("FullTypedThrows"),
.enableExperimentalFeature("IsolatedAny"),
.swiftLanguageMode(.v6)
]
),

.target(
name: "TetraRunLoopConcurrency",
dependencies: [
"CriticalSection",
.product(name: "Atomics", package: "swift-atomics"),
.product(name: "HeapModule", package: "swift-collections"),
.product(name: "BasicContainers", package: "swift-collections"),
.product(name: "ContainersPreview", package: "swift-collections"),
],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency=complete"),
.swiftLanguageMode(.v6),
.enableExperimentalFeature("BuiltinModule"),
]
),
.target(
name: "BackPortAsyncSequence",
dependencies: [ "Namespace"],
swiftSettings: [
.swiftLanguageMode(.v6),
]
),
.testTarget(
name: "TetraTests",
dependencies: [
"Tetra"
],
resources: [.process("Resources")]
)
]
resources: [.process("Resources")],
swiftSettings: [
.swiftLanguageMode(.v5)
]
),
.testTarget(
name: "TetraRunLoopConcurrencyTests",
dependencies: ["TetraRunLoopConcurrency"],
swiftSettings: [
.swiftLanguageMode(.v6),
.unsafeFlags(["-Xfrontend", "-disable-availability-checking"]),

]
),
],
)
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,16 @@ import Combine

let cancellable = (0..<20).publisher
.setFailureType(to: URLError.self)
.multiMapTask(maxTasks: .unlimited) { _ in
.multiMapTask(maxTasks: .unlimited) { _ throws(URLError) in

// Underlying Task is cancelled if subscription is cancelled before task completes.
do {
let (data, response) = try await URLSession.shared.data(from: URL(string: "https://google.com")!)
return .success(data) as Result<Data,URLError>
// below unsafe cancel is no-op, throw appropriate error to interrupt combine pipeline
// withUnsafeCurrentTask { $0?.cancel() }
return data
} catch {
return .failure(error as! URLError) as Result<Data,URLError>
throw (error as! URLError)
}
}.sink { completion in

Expand All @@ -101,8 +104,7 @@ import Tetra
continuation.yield(1)
continuation.finish()
// Underlying AsyncIterator and Task receive task cancellation if subscription is cancelled.
}.tetra.publisher
.catch{ _ in Empty().setFailureType(to: Never.self) }
}.tetra.bridge.tetra.publisher
.sink { number in

}
Expand Down Expand Up @@ -188,3 +190,38 @@ struct ContentView: View {
- more fine grained way to introduce extension methods (maybe something like `.af` in Alamofire?)

- remove all `AsyncTypedSequence` and `WrappedAsyncSequence` dummy protocol when `FullTypedThrow` is implemented.

## WIP

[PriorityRunLoop](./Sources/Tetra/Concurrency/PriorityRunLoop.swift)

TaskPriority aware NSRunLoop based `Concurrency Serial Executor`.

Can be useful for old Apple Framework that does not support `libDispatch` and only support `CFRunLoop` like `CoreLocation`, `perform(_:on:with:waitUntilDone:)`

Reorder the jobs in Priority Order, and increase QoS level, according to the TaskPriority.


[AsyncFlatMap](./Sources/Tetra/Combine/Publishers+AsyncFlatMap.swift)

Combine operator which convert the Upstream to AsyncSequence and transfer the elements to the downstream.

uses actor based cooperative control to minimize contention.

Investingating for a way to backport rich asyncSequence features before Swift 6 platform.


[BackportDiscardingTaskGroup](./Sources/BackportDiscardingTaskGroup/ThrowingTaskGroup.swift)

Backport the behavior of `Discarding(Throwing)TaskGroup`. This now possbile thanks to Swift 6 generalized AsyncSequnce. Because we can wrap the `TaskGroup` into isolation.

Investingating for a way to merge it with existing `Discarding(Throwing)TaskGroup` using some kind of opaque types rather than erased types.

Investigating a way to merge NonFailure type and Failing type using typedThrow, which is currently not possible due to Swift 6 compiler bug.


[MemorySafe Data/String](./Sources/Tetra/Foundation/PruneMemory.swift)

`Data` and `String` which erase its memory footprints when deallocated. implemented by `CoreFoundation` API.

Still can not erase memory footprints caused by Swift Briding copy and os level memory paging.
Loading