MdYamlDocLoader: Load the docs in another isolate

This will hopefully make opening the app a bit better as the yaml
parsing is now in another thread and frames would no longer be skipped.
This commit is contained in:
Vishesh Handa
2020-03-15 00:12:36 +01:00
parent b0cc615aae
commit d8464ff64f

View File

@ -1,23 +1,64 @@
import 'dart:io'; import 'dart:io';
import 'dart:isolate';
import 'package:gitjournal/core/md_yaml_doc.dart'; import 'package:gitjournal/core/md_yaml_doc.dart';
import 'package:gitjournal/core/md_yaml_doc_codec.dart'; import 'package:gitjournal/core/md_yaml_doc_codec.dart';
class MdYamlDocLoader { class MdYamlDocLoader {
static final _serializer = MarkdownYAMLCodec(); Isolate _isolate;
ReceivePort _receivePort = ReceivePort();
SendPort _sendPort;
Future<void> _initIsolate() async {
if (_isolate != null) return;
_isolate = await Isolate.spawn(_isolateMain, _receivePort.sendPort);
var data = await _receivePort.first;
assert(data is SendPort);
_sendPort = data as SendPort;
}
Future<MdYamlDoc> loadDoc(String filePath) async { Future<MdYamlDoc> loadDoc(String filePath) async {
// FIXME: What about parse errors? await _initIsolate();
final file = File(filePath); final file = File(filePath);
if (!file.existsSync()) { if (!file.existsSync()) {
throw MdYamlDocNotFoundException(filePath); throw MdYamlDocNotFoundException(filePath);
} }
var rec = ReceivePort();
_sendPort.send(_LoadingMessage(filePath, rec.sendPort));
var data = await rec.first;
assert(data is MdYamlDoc);
return data;
}
}
class _LoadingMessage {
String filePath;
SendPort sendPort;
_LoadingMessage(this.filePath, this.sendPort);
}
void _isolateMain(SendPort toMainSender) {
ReceivePort fromMainRec = ReceivePort();
toMainSender.send(fromMainRec.sendPort);
final _serializer = MarkdownYAMLCodec();
fromMainRec.listen((data) async {
assert(data is _LoadingMessage);
var msg = data as _LoadingMessage;
final file = File(msg.filePath);
final fileData = await file.readAsString(); final fileData = await file.readAsString();
var doc = _serializer.decode(fileData); var doc = _serializer.decode(fileData);
return doc;
} msg.sendPort.send(doc);
});
} }
class MdYamlDocNotFoundException implements Exception { class MdYamlDocNotFoundException implements Exception {