Concurrency Orchestration -Ā Swift by Sundell #95
Having dealt with concurrency and data synchronization issues in the past, Iām always interested to hear how other folks approach that problem set. With that in mind I checked out Swift by Sundell Episode #95Ā āConcurrency orchestrationā with special guest Brent Simmons.Ā I usually keep these notes in order of the discussion in the podcast, but Iāve reorganized this time to keep related topics together.Ā
You usually want to be pushing background work onto a serial queue.
Want to stay on main thread unless thereās a really solid reason not to. Write it the ideal way. If you see a blocker, use profiler and see whatās the root cause.
Identify things that need to go in the background and make them self contained (example rss parsing, parsing data and turning into model object). During parsing you shouldnāt be doing anything that could affect the rest of the app. Put the work on a serial queue and callback on the main thread.
The fact that something is on a background thread should not leak. Send the operation to the background queue, then callback at the end. Donāt have the background thread sending notifications or doing other things that leak knowledge that it is background work.
Threading leads to so much uncertainty and problems. Reducing areas of moving back & forth makes your code more resilient.
Going from main to background to another background can be okay, but consider treating it as a stack and moving data back up rather than cutting straight back to a previous queue/main queue.
Sharing mutable data across threads is setting self up for crashes or data inconsistencies
serial queue for reads & writes that calls back onto main queue
Always calling back on main thread
Apple tends to callback on thread work performed on.
URLSession does work on background then calls your callback also on background.
Can lead to data races, or calling UI APIs from background threads.
Need to look out for these and make sure UI work is going back on main queue.
Can write code such that you accept a callback queue but have it default to main so you can choose a different queue if necessary.
Performance problems on main thread
Many developers tend to drop to work to background threads before profiling to know where the issue is coming from.
Not everything can be solved with concurrency. The problem might manifest as a lot time in a function, but a background thread might be a bandaid rather than solving the issue.
Role is to find simpler solutions, find the simplest way to create a performant experience, not complicated code.
Brent Simmons project - NetNewsWire
Originally Mac only (project started pre-iPhone). Rewritten in 2014.Ā
Created version of the app using SwiftUI & combine only, did not ship since performance wasnāt where they wanted things to be, but held onto that code.Ā
They are using a couple pieces of SwiftUI in shipping app, but mostly waiting to fully shift over to SwiftUI
Mac vs phone SwiftUIMac performance noticeably less than on iPhone. large reason chose not to switch over to SwiftUI after investing time was degraded performance on Mac
Anyone can join the open source development of net news wire:
Join the slack group and āworkā channel
Talk about what youāre interested in building or ask for a bug to work on
Concurrency for NetNewsWire
objects are never mutable on main
Has a single background queue for database operations
Status objects (read/starred) is reference object created & mutated on a background serial queue
Any thread can say to update the āreadā status, but that āreadā status is only ever updated on the one synchronized queue.
How are you handling threads in your project?
Does your background work callback on background or main?
Is your background thread sending notifications or other things that leak background status?
When you move work to background threads, are you first profiling your app to understand root cause?