refactor(shorebird_cli): use Isolate.run (#32)
This commit is contained in:
@@ -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);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user