iganin
October 02, 2021

# Data Race and Actor

Presentation about data race and actor.

October 02, 2021

## Transcript

2. ### Abstract Explain what data race is, and show example of

it. Then explain how to resolve this issue in old way, and new way. He use serial queue in old way, and Actor in new way.
3. ### Agenda • Data Race • Data Race Demo • Old

Solution with serial queue • Concurrency in Swift 5.5 • New Solution with Actor
4. ### Agenda • Data Race • Data Race Demo • Old

Solution with serial queue • Concurrency in Swift 5.5 • New Solution with Actor

same shared variable data.
6. ### Data Race Thread A Thread A var balance = 1000

func deposit(amount: Int) -> Int BankAccount Considering situation there are thread A and bank account instance. when only thread A access bank account there will be no problem. balance 1000 deposit 1000 -> balance 2000 balance 2000 deposit 1000 -> balance 3000
7. ### Data Race Thread A Thread B var Balance = 1000

func deposit(amount: Int) -> Int BankAccount Consider situation when thread A and thread B access bank account data at the same time.
8. ### Data Race Thread A Thread B var balance = 1000

func deposit(amount: Int) -> Int BankAccount In this case, behavior become unpredictable. For example, when thread A and B access at the same time, read 1000 and deposit value at the same time, then balance may become 2000. balance 1000 deposit 1000 -> balance 2000 balance 1000 deposit 1000 -> balance 2000
9. ### Data Race Thread A Thread B var balance = 1000

func deposit(amount: Int) -> Int BankAccount The result is huge problem ( where my deposit goes… ) balance 1000 deposit 1000 -> balance 2000 balance 1000 deposit 1000 -> balance 2000 Deposit 2000 But only 1000 was added😱
10. ### Agenda • Data Race • Data Race Demo • Old

Solution with fixed queue • Concurrency in Swift 5.5 • New Solution with Actor
11. ### Data Race Demo class DataRaceBankAccount { private var balance =

0 func deposit(amount: Int) -> Int { balance += amount return balance } } DispatchQueue.concurrentPerform(iterations: 10) { i in print(dataRaceBankAccount.deposit(amount: 1000)) }
12. ### Data Race Demo let dataRaceBankAccount = DataRaceBankAccount() DispatchQueue.concurrentPerform(iterations: iteration) {

_ in let balance = dataRaceBankAccount.deposit(amount: 1000) print("dataRaceBankAccount: \(balance)") } DispatchQueue.concurrentPerform will use threads and perform its prop process concurrently. So we can produce situation for data race.
13. ### Agenda • Data Race • Data Race Demo • Old

Solution with serial queue • Concurrency in Swift 5.5 • New Solution with Actor
14. ### Old Solution with fixed queue To avoid data race, we

can use some solutions • lock(semaphore etc) • serial queue I’d like to focus on fixed queue.
15. ### Using Serial Queue class QueueBankAccount { private let queue =

DispatchQueue(label: UUID().uuidString) // serial queue private var balance = 0 func deposit(amount: Int, completion: @escaping ((Int) -> Void)) -> Void { queue.async { [self] in self.balance += amount completion(self.balance) } } } Above class have serial queue, and we can access balance via that queue, which means we can access its balance only via same thread.
16. ### Serial Queue Thread A Thread C var balance = 1000

BankAccount We can access balance only via thread D through deposit function. Thread B Thread D func deposit(amount: Int) -> Int
17. ### Serial Queue Demo DispatchQueue.concurrentPerform(iterations: iteration) { _ in queueBankAccount.deposit(amount: 1000)

{ balance in print("queueBankAccount: \(balance)") } }
18. ### Agenda • Data Race • Data Race Demo • Old

Solution with serial queue • Concurrency in Swift 5.5 • New Solution with Actor
19. ### Swift 5.5 Concurrency The new concept for concurrency is introduced

in Swift 5.5. They are async / await, sendable, and actor. actor is today’s main topic.
20. ### Async Await Async function with completion handler https://speakerdeck.com/hironobuiga/20210625-meet-async-await-at-swiftai-hao-hui?slide=12 • it

doesn’t force call completion handler which means we can make bug easily • deep nest • difficult to read because of out of order Async function with async / await https://speakerdeck.com/hironobuiga/20210625-meet-async-await-at-swiftai-hao-hui?slide=17 • it force returning value • no nest, very simple • very simple order from top to bottom
21. ### Agenda • Data Race • Data Race Demo • Old

Solution with serial queue • Concurrency in Swift 5.5 • New Solution with Actor
22. ### What is Actor The actor model is a conceptual model

to deal with concurrent computation. It defines some general rules for how the system’s components should behave and interact with each other. https://www.brianstorti.com/the-actor-model/ Hmmm…. Above definition is too abstract, so let’s check swift usage.
23. ### Swift Actor actor Counter { var count = 0 func

increase() { count += 1 } } • Reference Type • don’t support inheritance • enforce synchronized access to its mutable property / mutation method ◦ it prevent data racing
24. ### Swift Actor actor Counter { var count = 0 func

increase() { count += 1 } } counter.increase() // compile error await counter.increase() Actor enforce synchronized access, so we can access mutable data only via async / await.
25. ### Example actor ActorBankAccount { private var balance = 0 func

deposit(amount: Int) async -> Int { balance += amount return balance } } We can define actor class with using `actor`. As you can see, the definition is very simple and almost same as not actor one.
26. ### Actor Demo DispatchQueue.concurrentPerform(iterations: 10) { _ in Task.detached { let

balance = await actorBankAccount.deposit(amount: 1000) print("actorBankAccount: \(balance)") } } We should use Task {} to use async / await func.
27. ### Merit of Actor • it enforce synchronization ◦ when use

serial queue, it depends on us whether we implement it correctly or not • very simple
28. ### But…. We can use swift new concurrency system from Swift

5.5. But it depends on OS currently. We can use concurrency with above iOS15… Currently swift contributor works on back to older version. And it seems that we will be able to use Swift new concurrency under iOS version under 15. https://forums.swift.org/t/will-swift-concurrency-deploy-back-to-older-oss/49370