Jordhan Léoture (Octo) - Asynchronous Swift
Comment simplifier et améliorer l’asynchronisme dans nos applications ?
Je vous présenterai quelques astuces afin d’exploiter au mieux GCD.
5. PARALLELISM & CONCURRENCY
Grand Central Dispatch
5
• Reduces memory for storing thread stacks
• Reduces code related to thread
management
• Simplifies code
13. PARALLELISM & CONCURRENCY
Concurrency - Example
12
CONTEXT SWITCH
• Save the context of the current thread
• Find the context of the next thread
• Reload the context of the next thread
• Resume the next thread
14. PARALLELISM & CONCURRENCY
Concurrency - Example
13
The OS chooses the next thread
• A higher priority thread needs the CPU
• The current thread finishes its work
• The current thread is waiting for a resource
• The time of the current thread has expired
21. FAIR LOCK & UNFAIR LOCK
FAIR LOCK
No waiter starvation but many context switches
UNFAIR LOCK
Subject to waiter starvation but reduced context switches
20
22. FAIR LOCK & UNFAIR LOCK
21
FAIR LOCK
(dispatch_semaphore)
UNFAIR LOCK
(os_unfair_lock)
TIME BY LOCK LONG SHORT
# LOCK BY THREAD FEW MANY
# THREAD NEED THE
LOCK
MANY FEW
23. FAIR LOCK & UNFAIR LOCK
Recurring problems
22
• Frequently block threads for resource access
• Many context switch between independent operations
25. DISPATCHQUEUE
• Perform tasks asynchronously and concurrently
• FIFO
• Thread-safe
• Serial or concurrent
24
Good to know
26. DISPATCHQUEUE
25
Quality of Service Classes
User-interactive Virtually instantaneous
User-initiated Nearly instantaneous
Default No information
Utility Seconds or few minutes
Background Minutes or hours
Unspecified Legacy APIs
High
Low
52. FUTURE & PROMISE
Example
35
let promise = Promise<Int>()
let future = promise.future
queue1.async {
future.then { i in /* success */ }
.catch { error in /* failure */ }
}
53. FUTURE & PROMISE
Example
36
let promise = Promise<Int>()
let future = promise.future
queue1.async {
future.then { i in /* success */ }
.catch { error in /* failure */ }
}
queue2.async {
promise.resolve { 1 }
}
54. FUTURE & PROMISE
Example
37
service.call(request: "…") { result in
switch result {
case let .success(data):
service.call(request: "…") { result in
switch result {…}
/* finally do something */
}
case let .failure(error): /* failure */
}
/* finally do something */
}
55. FUTURE & PROMISE
Example
38
service.call(request: "…") { result in
switch result {
case let .success(data):
service.call(request: "…") { result in
switch result {…}
/* finally do something */
}
case let .failure(error): /* failure */
}
/* finally do something */
}
• Is the first completion on the same Thread
that the first service.call ?
• Is the second service.call on the same Thread
that the first completion ?
• Is the second completion on the same Thread
that the second service.call ?
56. FUTURE & PROMISE
Example
39
service.call(request: "…")
.then(qos: .utility) { data in service.call(request: "…") }
.then(qos: .userInteractive) { data in /* success */ }
.catch(qos: .userInteractive) { error in /* failure */ }
.finally(qos: .background) { /* do something */ }
57. FUTURE & PROMISE
Example
40
service.call(request: "…")
.then(qos: .utility) { data in service.call(request: "…") }
.then(qos: .userInteractive) { data in /* success */ }
.catch(qos: .userInteractive) { error in /* failure */ }
.finally(qos: .background) { /* do something */ }
internalQueue thencallthen finallycatch