refactor(shorebird_cli): use Isolate.run (#32)

This commit is contained in:
Felix Angelov
2023-03-07 10:36:10 -06:00
committed by GitHub
parent 7e7e7ab7bd
commit ede5f51fa2
3 changed files with 4 additions and 63 deletions
@@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:archive/archive_io.dart';
import 'package:args/command_runner.dart';
@@ -7,7 +8,6 @@ import 'package:mason_logger/mason_logger.dart';
import 'package:path/path.dart' as p;
import 'package:shorebird_cli/src/auth/auth.dart';
import 'package:shorebird_cli/src/command_runner.dart';
import 'package:shorebird_cli/src/compute.dart';
import 'package:shorebird_code_push_api_client/shorebird_code_push_api_client.dart';
typedef StartProcess = Future<Process> Function(
@@ -157,12 +157,11 @@ Future<void> _extractShorebirdEngine(
targetDirectory.createSync(recursive: true);
await compute(
(path) async {
final inputStream = InputFileStream(path);
await Isolate.run(
() async {
final inputStream = InputFileStream(archivePath);
final archive = ZipDecoder().decodeBuffer(inputStream);
extractArchiveToDisk(archive, targetPath);
},
archivePath,
);
}
@@ -1,41 +0,0 @@
import 'dart:async';
import 'dart:isolate';
/// Perform [computation] with [input] in an [Isolate].
Future<R> compute<R, M>(FutureOr<R> Function(M) computation, M input) async {
final resultPort = ReceivePort();
final errorPort = ReceivePort();
await Isolate.spawn<_IsolateConfig<M, FutureOr<R>>>(
_spawn,
_IsolateConfig<M, FutureOr<R>>(computation, input, resultPort.sendPort),
onError: errorPort.sendPort,
);
final result = Completer<R>();
errorPort.listen((dynamic errorData) {
final data = errorData as List;
final exception = Exception(data[0]);
final stack = StackTrace.fromString(data[1] as String);
result.completeError(exception, stack);
});
resultPort.listen((dynamic resultData) => result.complete(resultData as R));
await result.future;
resultPort.close();
errorPort.close();
return result.future;
}
class _IsolateConfig<M, R> {
const _IsolateConfig(this.callback, this.message, this.resultPort);
final R Function(M message) callback;
final M message;
final SendPort resultPort;
FutureOr<R> compute() => callback(message);
}
Future<void> _spawn<R, M>(_IsolateConfig<R, FutureOr<M>> configuration) async {
Isolate.exit(configuration.resultPort, await configuration.compute());
}
@@ -1,17 +0,0 @@
import 'package:shorebird_cli/src/compute.dart';
import 'package:test/test.dart';
int test1(int value) => value + 1;
int test2(int value) => throw Exception();
Future<int> test1Async(int value) async => value + 1;
Future<int> test2Async(int value) async => throw Exception();
void main() {
test('compute()', () async {
expect(await compute(test1, 0), 1);
expect(compute(test2, 0), throwsException);
expect(await compute(test1Async, 0), 1);
expect(compute(test2Async, 0), throwsException);
});
}