Don't schedule work before a database is opened

This commit is contained in:
Simon Binder 2021-06-08 21:25:22 +02:00
parent 45196d070e
commit 1068c4934d
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
2 changed files with 39 additions and 3 deletions

View File

@ -2,13 +2,13 @@ import 'dart:async';
/// A single asynchronous lock implemented by future-chaining.
class Lock {
Future<void> _last = Future.value();
Future<void>? _last;
/// Waits for previous [synchronized]-calls on this [Lock] to complete, and
/// then calls [block] before further [synchronized] calls are allowed.
Future<T> synchronized<T>(FutureOr<T> Function() block) {
final previous = _last;
// This controller may not be sync: It must complete just after
// This completer may not be sync: It must complete just after
// callBlockAndComplete completes.
final blockCompleted = Completer<void>();
_last = blockCompleted.future;
@ -21,6 +21,10 @@ class Lock {
}
}
return previous.then((_) => callBlockAndComplete());
if (previous != null) {
return previous.then((_) => callBlockAndComplete());
} else {
return callBlockAndComplete();
}
}
}

View File

@ -0,0 +1,32 @@
import 'dart:async';
import 'package:moor/src/ffi/vm_database.dart';
import 'package:test/scaffolding.dart';
import '../data/tables/todos.dart';
void main() {
test('creating a database instance does not schedule async work', () {
// See https://github.com/simolus3/moor/issues/1235. We shouldn't run async
// work without users being aware of it, and no one expects creating an
// instance to schedule new microtasks.
noAsync(() => TodoDb(VmDatabase.memory()));
});
}
T noAsync<T>(T Function() fun) {
return runZoned(
fun,
zoneSpecification: ZoneSpecification(
scheduleMicrotask: (self, parent, zone, function) {
throw StateError('Not allowed: scheduleMicrotask');
},
createTimer: (self, parent, zone, duration, callback) {
throw StateError('Not allowed: createTimer');
},
createPeriodicTimer: (self, parent, zone, duration, callback) {
throw StateError('Not allowed: createPeriodicTimer');
},
),
);
}