tekartik / sembast_sqflite

sembast on top of sqflite
BSD 2-Clause "Simplified" License
13 stars 1 forks source link

Usage in multiple isolates #3

Closed kuhnroyal closed 6 months ago

kuhnroyal commented 4 years ago

I am not clear on the documented cross process database storage. Would this allow to open a separate Sembast instance in multiple isolates and access the same database?

alextekartik commented 4 years ago

Unfortunately no. sqflite itself is not multiple isolate safe regarding transactions. So i recommend using sembast from the main isolate. However using sqflite as a backend for sembast is cross process safe (i.e. 2 applications can access the same database without corruption) while sembast "io" (using a json file) itself is not cross process safe.

This mainly applies for Desktop (using sqflite_common_ffi) as on iOS/Android you only have one instance (or at least you can control to have only one instance).

kuhnroyal commented 4 years ago

Ok, then I am doing something wrong in general, I use databaseFactoryFfi from sqflite_common_ffi on iOS/Android.

Was hoping I could either share the instance with another isolate or at least open some kind of readonly instance in the background.

alextekartik commented 4 years ago

I have personally not tested ffi on iOS/Android so at this point I recommend using regular sqflite here. moor_ffi could help on the setup (and I'll be glad to know whether it works or not)

Operations already happens in a separate isolate using sqflite_common_ffi so no need to create yet another isolate (and as I said, it is not safe and completely untested and so far people managed without - although I know some tried/managed to open in read-only from another isolate).

kuhnroyal commented 4 years ago

Well I have been using it for a couple month on both platforms like this: :o

Future<Database> createPlatformSembastStore({
  @required int schemaVersion,
  OnVersionChangedFunction migrations,
}) async {
  final factory = getDatabaseFactorySqflite(databaseFactoryFfi);
  final dir = await paths.getApplicationDocumentsDirectory();
  if (!dir.existsSync()) {
    dir.createSync(recursive: true);
  }
  return factory.openDatabase(
    p.join(dir.path, 'sembast.sqlite'),
    version: schemaVersion,
    onVersionChanged: migrations,
  );
}
alextekartik commented 4 years ago

Ah yes! great! thanks for the info!. moor_ffi is definitely well implemented (although moor is not used here, its ffi implementation is great (sqflite_common_ffi just make it work in a separate isolate to avoid ui jank issues), maybe at some point the raw ffi implementation could be extracted to avoid any moor dependency (but it is always a pain to have yet another package to maintain...)

kuhnroyal commented 4 years ago

However using sqflite as a backend for sembast is cross process safe (i.e. 2 applications can access the same database without corruption) while sembast "io" (using a json file) itself is not cross process safe.

Ok I am still trying to wrap my head around this. Can I open a different Sembast instance from something like https://pub.dev/packages/background_fetch using the same database file when using sqflite_common_ffi?

alextekartik commented 4 years ago

sqflite itself is not cross isolate safe (!) so I don't recommend using it (and so sembast) from a separate isolate at this point. (although I have never used background_fetch so I'm not sure how it works)