multi-threaded coredata done right

Post on 24-Jan-2015

385 Views

Category:

Engineering

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides from my 360|iDev talk on how to concurrently fetch, parse, and save data while allowing user interaction to continue smoothly.

TRANSCRIPT

Multi-threaded Core Data Done Right

Andrew Morrow

Multi-threaded Core Data Done Right

Andrew Morrow

Let’s Build a CoreData Stack!

Goals

1. Never block UI interaction

2. Efficiently handle large datasets

3. Display updated data immediately

4. Avoid data merge conflicts

First Try (Demo)

What Went Wrong?

Main Queue Background Queue

getAsynchronous

Main Queue Background Queue

getAsynchronous

Main Queue Background Queue

Network Request

getAsynchronous

dispatch_async

Main Queue Background Queue

Main Queue MOC

Network Request

getAsynchronous

dispatch_async

! Parse and Save

Main Queue Background Queue

Main Queue MOC

Network Request

getAsynchronous

dispatch_async

! Parse and Save

User Interaction

Main Queue Background Queue

Main Queue MOC

Network Request

Move Parsing and Saving onto a Background Queue

(Demo)

What Went Wrong?

Main Queue Background Queue

getAsynchronous

Main Queue Background Queue

getAsynchronous

Main Queue Background Queue

Network Request

getAsynchronous

performBlock

Main Queue Background Queue

Background MOC

Network Request

getAsynchronous

performBlock

Parse and Save? User Interaction

Main Queue Background Queue

Background MOC

Network Request

getAsynchronous

performBlock

Parse and Save? User Interaction

Main Queue Background Queue

Background MOC

Network Request?!

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Solution: Multiple Persistent Store Coordinators

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Read-Only

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Read-Only

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Read-Only

Main Queue MOC

Background MOC

Persistent Store Coordinator

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Persistent Store Coordinator

Read-Only Read-Write

Write-Ahead Logging (WAL)

1 2 3 4 5

Reader(s)

Write-Ahead Logging (WAL)

1 2 3 4 5

Reader(s)

6

Writer

Write-Ahead Logging (WAL)

1 2 3 4 5

Reader(s)

6

Write-Ahead Logging (WAL)

1 2 3 4 5

Reader(s)

6

Write-Ahead Logging (WAL) (cont.)

SQLite feature

Multiple concurrent reads

One concurrent write

Shared memory between readers and writers for synchronization

Good News!

Good News!@{NSSQLitePragmasOption: @{@"journal_mode": @"WAL"}}

Parallel Persistent Store Coordinators

(Demo)

What Went Wrong?

Updating the Main Thread

Main Queue MOC

Background MOC

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Updating the Main Thread

Main Queue MOC

Background MOC

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Background MOC

Updating the Main Thread

Main Queue MOC

Background MOC

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Background MOC

SQLite

Updating the Main Thread

Main Queue MOC

Background MOC

User Interaction (Fetched Results Controller)

SQLite

Remote Data Refresh (Parse and Save)

Background MOC

SQLite

Updating the Main Thread (Cont.)Merging changes from notifications

Batched saves

Custom notifications

Completion blocks

NSManagedObjectID

Updating the Main Thread (Demo)

Avoiding Merge Conflicts

Serialize CoreData write access

Keep main thread read-only

SQLite (Jennifer)

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC (Jennifer)

SQLite (Jennifer)

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC (Jennifer)

Background MOC (Jen)

SQLite (Jennifer)

SQLite (Jen)

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC (Jennifer)

Background MOC (Jen)

SQLite (Jennifer)

SQLite (Jen)

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC (Jennifer)

Background MOC (Jen)

Main Queue MOC (Jen)

SQLite (Jennifer)

SQLite (Jen)

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC (Jennifer)

Background MOC (Jen)

Main Queue MOC (Jen)

→ Jen

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC Queue

→ Jen

SQLite (Jennifer)

→ Jen

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC Queue

→ Jen

SQLite (Jennifer)

→ Jen

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC Queue

→ Jen

SQLite (Jennifer)

SQLite (Jen)

→ Jen

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC Queue

→ Jen

SQLite (Jennifer)

SQLite (Jen)

Main Queue MOC (Jen)

→ Jen

Main Queue MOC (Jennifer)

User Interaction Jennifer → Jen

Remote Data Refresh Jennifer → Jen

Background MOC Queue

→ JenSQLite (Jennifer)

SQLite (Jen)

Main Queue MOC (Jen)

Summary

Let SQLite handle your concurrency

Only allow one concurrent write

Keep your main thread read-only

“CoreData Performance” Tim Isted, WWDC 2013 #211

Questions

Questions

top related