objectbox / objectbox-dart

Flutter database for super-fast Dart object persistence
https://docs.objectbox.io/getting-started
Apache License 2.0
927 stars 115 forks source link

10001 Cannot open store error on hot restart #387

Closed thezjy closed 2 years ago

thezjy commented 2 years ago

Basic info (please complete the following information):

Steps to reproduce

  1. start a Flutter + ObjectBox project in debug mode
  2. hot restart
  3. StateError (Bad state: failed to create store: 10001 Cannot open store: another store is still open using the same path: [path to the database file]

Expected behavior

In ObjectBox 1.3 the hot restart works correctly.

Additional context

I've done some search and it looks like there is no way to manually dispose resources on hot restart in Flutter.

richard457 commented 2 years ago

@thezjy @greenrobot @vaind please help us on this, it is very annoying to start the app everytime.

thezjy commented 2 years ago

@richard457 It is. In the meantime, you can switch back to version 1.3 which works fine.

greenrobot commented 2 years ago

no way to manually dispose resources on hot restart in Flutter

Just for the record: the updated check is "more accurate" from the native perspective. It seems like - whatever Flutter's hot reload does - there seems to be an "illegal" overlap in using native resources. Any pointers to Flutter resources would be helpful.

thezjy commented 2 years ago

@greenrobot Some related issues: https://github.com/flutter/flutter/issues/10437 https://github.com/flutter/flutter/issues/69949

richard457 commented 2 years ago

@richard457 It is. In the meantime, you can switch back to version 1.3 which works fine.

switching back when you have already run flutter packages pub run build_runner build --delete-conflicting-outputs does not work either.

ayanbabi90 commented 2 years ago

getting same error

ayanbabi90 commented 2 years ago

after switching back to v1.3 it's not working giving the same error "10001 Cannot open store error on hot restart"

greenrobot commented 2 years ago

When reading about app state, I wonder if it may work to make the Store part of the state that's being kept across hot-reload. E.g. create the store in a static function/main, and then pass the store to a class that initializes a final member with it?

greenrobot-team commented 2 years ago

Hot reload of the example works fine with 1.4.0 and using stable Flutter (2.10.2 with Dart 2.16.1) on an Android 12 emulator.

Given StateError (Bad state: failed to create store: 10001 Cannot open store: another store is still open using the same path: [path to the database file] is it possible that in your code Store is not kept in a global variable, but instead is re-created each time the app reloads? Or is this maybe an iOS only issue?

greenrobot-team commented 2 years ago

Sorry, my bad. I confused hot reload with hot restart. Can reproduce now!

greenrobot-team commented 2 years ago

TL;DR: it is currently not possible to use hot restart (Play button) with ObjectBox; hot reload works (lightning button or what happens on saving a file works fine, difference explained in Flutter docs). The workaround is to stop and then start the app again.

The underlying issue is that on hot restart (not hot reload, which works) a) Dart objects are cleared and b) native code state (used through FFI) is not cleared. So while in Dart state is gone (e.g. pointers, open database directories) the state is kept in native code, e.g. the store is still open.

Creating and disposing Store within a Flutter widget (like the examples did previously) wouldn't help, since dispose() isn't called on hot restart.

There is currently no Flutter or Dart API to be notified about a hot restart. Issues for this:

A possible solution implemented by another Flutter plugin is to dispose any existing state in native code when Store appears to be first initialized.

greenrobot-team commented 2 years ago

@thezjy @richard457 @ayanbabi90 If you are up to it, you can try the just released preview release 1.4.1-dev.0. Let us know if it resolves the reported exception on Flutter hot restart and introduces no other issues!

Technical background: Store now attaches a C finalizer using the native Dart SDK that closes the native store if the Dart instance is garbage collected (see #390). This appears to work with Flutter hot restart in my tests (Android 12 emulator). If successful, we also might want to report this to the above issues as a possible workaround when using FFI.

scalz commented 2 years ago

I quickly tested your preview, and it seems working well so far, on my side, hot restart/play button is ok. I didn't try to revert to 1.3, and was patiently waiting..I was sure it would be fixed pretty fast ^^ I tested on Android 11 emulator, and a few functionalities in my app. isClosed can be handy. thank you!

richard457 commented 2 years ago

It also works on my windows/android app as well. @greenrobot @greenrobot-team

greenrobot-team commented 2 years ago

Released the fix with 1.4.1.

orestesgaolin commented 2 years ago

Do I think correctly that this issue still occurs when using runIsolated?

greenrobot-team commented 2 years ago

@orestesgaolin It shouldn't. The attached Store used for runIsolated also has a finalizer. Anyhow, that API will see a few fixes for the next release. But feel free to submit an issue with more details!

greenrobot-team commented 2 years ago

No further comments, so closing this.

BLB-EN438 commented 2 years ago

@greenrobot-team I am using objectbox:^1.4.1 If we manually closes the app by pressing the device back button and then again open the app from background app, I am still getting this error. Bad state: failed to create store: 10001 Cannot open store: another store is still open using the same path: "/data/data/com.example.name/app_flutter/objectbox".

greenrobot-team commented 2 years ago

@BLB-EN438 But this isn't related to Flutter hot restart then, no? Can you please create a new issue with more details on how to reproduce this?

Jaquelinebertoldo commented 2 years ago

Também tenho o mesmo problema, e nao consigo soluciona-lo, ja tentei todas as opções acima, mas sem sucesso, continua dando o mesmo erro, mesmo fechando o aplicativo por completo, no primeiro teste ja ocorre o erro. "Erro ao inicializar o banco de dados: Bad state: failed to create store: 10001 Cannot open store: another store is still open using the same path: "......."

greenrobot-team commented 2 years ago

@Jaquelinebertoldo Please post in English only so everyone can understand! It sounds like your trying to run tests. Make sure to store.close() before creating a new Store, or use a different directory for each created store. If that doesn't solve your problem, please create a new issue with more details on what you are trying to do so we can reproduce your issue.

animedev1 commented 1 year ago

How to solve this error ? I'm using 1.5.0 and getting the same error after pressed back button to exit app

greenrobot-team commented 1 year ago

Moved this new issue to #442, please continue to submit new info there.

user97116 commented 6 months ago

E/flutter (10735): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: failed to create transaction: Cannot start a write transaction inside a read only transaction (OBX_ERROR code 10001) E/flutter (10735): #0 ObjectBoxNativeError.throwMapped (package:objectbox/src/native/bindings/helpers.dart:74:9) E/flutter (10735): #1 throwLatestNativeError (package:objectbox/src/native/bindings/helpers.dart:54:48) E/flutter (10735): #2 checkObxPtr (package:objectbox/src/native/bindings/helpers.dart:31:5) E/flutter (10735): #3 new Transaction (package:objectbox/src/native/transaction.dart:33:5) E/flutter (10735): #4 Store._runInTransaction (package:objectbox/src/native/store.dart:712:32) E/flutter (10735): #5 InternalStoreAccess.runInTransaction (package:objectbox/src/native/store.dart:836:13) E/flutter (10735): #6 Box.put (package:objectbox/src/native/box.dart:94:34) E/flutter (10735): #7 TaskObjectBoxApi.addUpdate (package:progress/data/objectbox/apis/task_api.dart:15:44) E/flutter (10735): #8 UnplannedApi.onAdd (package:progress/migrate/domain/unplanned_api.dart:79:22) E/flutter (10735): #9 _AddUpdateUnplannedSubtaskPageState.onAdd (package:progress/migrate/views/unplanned/add_subtask/add_subtask_page.dart:178:10) E/flutter (10735): #10 _AddUpdateUnplannedSubtaskPageState.build. (package:progress/migrate/views/unplanned/add_subtask/add_subtask_page.dart:152:31) E/flutter (10735): E/flutter (10735): D/ColorViewRootUtil(10735): nav bar mode ignore false downX 191 downY 609 mScreenHeight 2340 mScreenWidth 1080 mStatusBarHeight 54 globalScale 1.125 nav mode 0 rotation 0 event MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=191.0, y[0]=609.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=70454557, downTime=70454557, deviceId=6, source=0x1002, displayId=0 } E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory D/ColorViewRootUtil(10735): nav bar mode ignore false downX 113 downY 185 mScreenHeight 2340 mScreenWidth 1080 mStatusBarHeight 54 globalScale 1.125 nav mode 0 rotation 0 event MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=113.0, y[0]=185.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=70455241, downTime=70455241, deviceId=6, source=0x1002, displayId=0 } E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory I/chatty (10735): uid=12708(amar.progress) identical 8 lines E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory I/TRuntime.CctTransportBackend(10735): Making request to: https://firebaselogging.googleapis.com/v0cc/log/batch?format=json_proto3 I/TRuntime.CctTransportBackend(10735): Status Code: 200 E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory I/chatty (10735): uid=12708(amar.progress) identical 5 lines E/UIFirst (10735): failed to open /proc/10735/stuck_info, No such file or directory