Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrent modification during iteration #13

Closed
cw-dev opened this issue Mar 30, 2019 · 1 comment
Closed

Concurrent modification during iteration #13

cw-dev opened this issue Mar 30, 2019 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@cw-dev
Copy link

cw-dev commented Mar 30, 2019

I was playing with the example project and came across this exception

E/flutter ( 5999): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: Concurrent modification during iteration: _LinkedHashMap len:2.
E/flutter ( 5999): #0      _CompactIterator.moveNext (dart:collection/runtime/libcompact_hash.dart:443:7)
E/flutter ( 5999): #1      FollowedByIterator.moveNext (dart:_internal/iterable.dart:855:26)
E/flutter ( 5999): #2      WhereIterator.moveNext (dart:_internal/iterable.dart:438:22)
E/flutter ( 5999): #3      StreamQueryStore.handleTableUpdates (package:moor/src/runtime/executor/stream_queries.dart:94:24)

The changes I made to the example project:


--- moor_flutter/example/lib/widgets/homescreen.dart
+++ moor_flutter/example/lib/widgets/homescreen.dart
@@ -102,7 +102,9 @@
     if (controller.text.isNotEmpty) {
       // We write the entry here. Notice how we don't have to call setState()
       // or anything - moor will take care of updating the list automatically.
-      bloc.addEntry(TodoEntry(content: controller.text));
+      int id = DateTime.now().millisecondsSinceEpoch;
+      bloc.addCategory(Category(id: id, description: "some category"));
+      bloc.addEntry(TodoEntry(category: id, content: controller.text));
       controller.clear();
     }
   }
--- moor_flutter/example/lib/widgets/todo_card.dart
+++ moor_flutter/example/lib/widgets/todo_card.dart
@@ -45,6 +45,12 @@
                 children: [
                   Text(entry.content),
                   dueDate,
+                  StreamBuilder<Category>(
+                    stream: BlocProvider.provideBloc(context).getCategory(entry.category),
+                    builder: (_, snap) {
+                      return Text(snap.data?.description ?? "");
+                    },
+                  ),
                 ],
               ),
             ),
@simolus3 simolus3 added the bug Something isn't working label Mar 30, 2019
@simolus3
Copy link
Owner

Thanks for the report.
I'm pretty sure I know where the concurrent modification error is coming from and I'll fix it in the next release. As a workaround, I suggest to either

  • await the insertion of the category before inserting the todo entry
  • start a transaction and execute both queries in there (this is more efficient, as queries that read from categories and todos would only be updated once in that case, whereas they would first react to the updated categories table and then to the updated todos table with the first solution.)

I see that the very primitive use of the bloc pattern in the example is of no help here, I'll have to clean that up a bit as well.

This is only semi-related to the issue, but I see you're creating a stream in each TodoCard. This could result in some performance problems, as every of these streams will fetch its data again whenever the categories table changes. For now, my suggestion would be a custom query that uses a join to load the category for each todo entry. I'll hopefully implement an easy api for joins soon, which will make this easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants