Prorsum
A Go like current system for Swift
Features
- OperationQueue based Concurrent System
- WaitGroup
- Once
- Channels
- Channel Iteration
- Select
- Timers
Installation
Currenty Prorsum supports only SPM.
SPM
import PackageDescription
let package = Package(
name: "MyApp",
dependencies: [
.Package(url: "https://github.com/noppoMan/Prorsum.git", majorVersion: 0, minor: 1),
]
)
Cocoapods
Not supported yet
Carthage
Not supported yet
Usage
go
go is an alias of OperationQueue.addOperation { }
func asyncTask(){
print(Thread.current)
}
go(asyncTask())
go {
print(Thread.current)
}
WaitGroup
A WaitGroup waits for a collection of BlockOperations
to finish. The main BlockOperation
calls Add to set the number of BlockOperations
to wait for. Then each of the BlockOperations
runs and calls Done when finished. At the same time, Wait can be used to block until all BlockOperations
have finished.
let wg = WaitGrpup()
wg.add(1)
go {
sleep(1)
print("wg: 1")
wg.done()
}
wg.add(1)
go {
sleep(1)
print("wg: 2")
wg.done()
}
wg.wait() // block unitle twice wg.done() is called.
print("wg done")
Channel<Element>
Channels are the pipes that connect concurrent operation. You can send values into channels from one BlockOperation
and receive those values into another BlockOperation
.
let ch = Channel<String>.make(capacity: 1)
func asyncSend(){
try! ch.send("Expecto patronum!")
}
go(asyncSend()) // => Expecto patronum!
go {
try! ch.send("Accio!")
}
try! ch.receive() // => Accio!
ch.close()
select
The select statement lets a BlockOperation
wait on multiple communication operations.
let magicCh = Channel<String>.make(capacity: 1)
go {
try! magicCh.send("Obliviate")
}
select {
when(magicCh) {
print($0)
}
otherwise {
print("otherwise")
}
}
forSelect
Generally You need to wrap the select inside a while loop. To make it easier to work with this pattern You can use forSelect
. forSelect will loop until done()
is called.
let magicCh = Channel<String>.make(capacity: 1)
let doneCh = Channel<String>.make(capacity: 1)
go {
try! magicCh.send("Crucio")
try! magicCh.send("Imperio")
}
go {
try! doneCh.send("Avada Kedavra!")
}
select { done in
when(magicCh) {
print($0)
}
when(doneCh) {
done() // break current loop
}
otherwise {
print("otherwise")
}
}
License
Prorsum is released under the MIT license. See LICENSE for details.