fix: Resolve SQLITE_BUSY by enabling WAL and fixing isolate init
This commit is contained in:
parent
14161727d5
commit
4cc822c4f6
|
|
@ -256,16 +256,28 @@ Future<void> _storageWorkerEntry(_WorkerInit init) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
final commandPort = ReceivePort();
|
final commandPort = ReceivePort();
|
||||||
init.responsePort.send(<String, Object?>{
|
|
||||||
'type': _msgReady,
|
|
||||||
'sendPort': commandPort.sendPort,
|
|
||||||
});
|
|
||||||
|
|
||||||
final storage = switch (init.backend) {
|
final storage = switch (init.backend) {
|
||||||
IsolateStorageBackend.sqlite => SqfliteEventStorage(),
|
IsolateStorageBackend.sqlite => SqfliteEventStorage(),
|
||||||
IsolateStorageBackend.memory => _MemoryEventStorage(),
|
IsolateStorageBackend.memory => _MemoryEventStorage(),
|
||||||
};
|
};
|
||||||
await storage.init();
|
|
||||||
|
try {
|
||||||
|
await storage.init();
|
||||||
|
} on Object catch (e, st) {
|
||||||
|
Logger.error('Isolate 存储初始化失败', e, st);
|
||||||
|
// 初始化失败时,不发送 ready 信号,或发送错误信号(当前协议简单,暂不发送 ready 即视为失败/超时)。
|
||||||
|
// 但为了让主 isolate 能够尽快失败而不是超时,我们可以考虑扩展协议,但目前最稳妥的是让主 isolate 超时抛错。
|
||||||
|
// 这里简单地关闭端口退出。
|
||||||
|
commandPort.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化成功后再发送 ready 信号。
|
||||||
|
init.responsePort.send(<String, Object?>{
|
||||||
|
'type': _msgReady,
|
||||||
|
'sendPort': commandPort.sendPort,
|
||||||
|
});
|
||||||
|
|
||||||
await for (final message in commandPort) {
|
await for (final message in commandPort) {
|
||||||
if (message is! Map) {
|
if (message is! Map) {
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,8 @@ class SqfliteEventStorage implements EventStorage {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final directory =
|
final directory = await (_documentsDirectoryProvider?.call() ??
|
||||||
await (_documentsDirectoryProvider?.call() ??
|
getApplicationDocumentsDirectory());
|
||||||
getApplicationDocumentsDirectory());
|
|
||||||
final dbPath = p.join(directory.path, DbConstants.dbName);
|
final dbPath = p.join(directory.path, DbConstants.dbName);
|
||||||
|
|
||||||
final factory = _databaseFactory ?? databaseFactory;
|
final factory = _databaseFactory ?? databaseFactory;
|
||||||
|
|
@ -56,6 +55,15 @@ class SqfliteEventStorage implements EventStorage {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// coverage:ignore-end
|
// coverage:ignore-end
|
||||||
|
onConfigure: (Database db) async {
|
||||||
|
// 启用 WAL 模式以支持更高并发读写,减少 SQLITE_BUSY。
|
||||||
|
// 注意:PRAGMA journal_mode 会返回结果,使用 execute 在 Android 上可能会报错,需改用 rawQuery。
|
||||||
|
await db.rawQuery('PRAGMA journal_mode = WAL;');
|
||||||
|
},
|
||||||
|
onOpen: (Database db) async {
|
||||||
|
// 确保表存在(针对多个 Store 共享同一 DB 文件且部分表可能未创建的情况)。
|
||||||
|
await _createTables(db);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -72,8 +80,7 @@ class SqfliteEventStorage implements EventStorage {
|
||||||
);
|
);
|
||||||
''');
|
''');
|
||||||
|
|
||||||
const createIndexSql =
|
const createIndexSql = 'CREATE INDEX IF NOT EXISTS idx_events_create_time '
|
||||||
'CREATE INDEX IF NOT EXISTS idx_events_create_time '
|
|
||||||
'ON $_tableEvents(create_time);';
|
'ON $_tableEvents(create_time);';
|
||||||
await db.execute(createIndexSql);
|
await db.execute(createIndexSql);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue