realm-swift icon indicating copy to clipboard operation
realm-swift copied to clipboard

Improve docs on usage on background thread

Open astigsen opened this issue 8 years ago • 2 comments

We still see a lot of people running into problems with users pinning Realms when using them on background threads, with a bloating of the file size as result.

Wo mention in the documentation that they should call refresh() regularly to avoid pinning, but that still leaves a risk of having Realm objects hanging around not being refreshed while the thread is blocked doing work or just inactive.

We should improve the docs to show examples of more robust ways to deal with realms on background threads, whether that is by recommending the use of explicit runloops or patterns for closing the realm when not in active use.

@andkon

astigsen avatar Jan 03 '17 23:01 astigsen

@jpsim, it'd be really nice to have a pattern/anti-pattern. Our devs are debating what this paragraph actually means:

Realm read transaction lifetimes are tied to the memory lifetime of Realm instances. Avoid “pinning” old Realm transactions by using auto-refreshing Realms and wrapping all use of Realm APIs from background threads in explicit autorelease pools.

Reference: https://realm.io/docs/swift/latest/#file-size-and-tracking-of-intermediate-versions

semireg avatar May 30 '17 18:05 semireg

Anti-pattern:

DispatchQueue(label: "bg").async {
  _ = try! Realm()
  // ^ no autoreleasepool, ARC won't release right away (or ever),
  // Realm won't know how long it needs to keep the data at this
  // version around for you to access.
}
let realm = try! Realm()
try! realm.write { /**/ }
try! realm.write { /**/ }
// lots of writes, Realm is advancing, maybe deleting data...
try! realm.write { /**/ }

Better pattern:

DispatchQueue(label: "bg").async {
  autoreleasepool {
    _ = try! Realm()
  }
  // ^ explicit autoreleasepool, ARC guarantees that the `Realm`
  // instance will be released by the end of its scope, meaning
  // that Realm knows you don't need the data at that version
  // anymore, so it can mark it as "free space" in the file.
}
let realm = try! Realm()
try! realm.write { /**/ }
try! realm.write { /**/ }
// lots of writes, Realm is advancing, maybe deleting data...
try! realm.write { /**/ }

jpsim avatar Jun 02 '17 20:06 jpsim