mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
a5f25ee3ba
Adds static method on `Isolate` to run an asynchronous function in a separate isolate. Change-Id: I673373fa02524f1d0b88099027cfaf1b796eb344 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254960 Commit-Queue: Lasse Nielsen <lrn@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
125 lines
3.7 KiB
Dart
125 lines
3.7 KiB
Dart
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:isolate';
|
|
import 'dart:async';
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'package:expect/expect.dart';
|
|
|
|
void main() async {
|
|
asyncStart();
|
|
// Sending result back.
|
|
await testValue();
|
|
await testAsyncValue();
|
|
// Sending error from computation back.
|
|
await testError();
|
|
await testAsyncError();
|
|
// Sending uncaught async error back.
|
|
await testUncaughtError();
|
|
// Not sending anything back before isolate dies.
|
|
await testIsolateHangs();
|
|
await testIsolateKilled();
|
|
await testIsolateExits();
|
|
// Failing to start.
|
|
await testInvalidMessage();
|
|
asyncEnd();
|
|
}
|
|
|
|
final StackTrace stack = StackTrace.fromString("Known Stacktrace");
|
|
final ArgumentError error = ArgumentError.value(42, "name");
|
|
|
|
var variable = 0;
|
|
|
|
Future<void> testValue() async {
|
|
var value = await Isolate.run<int>(() {
|
|
variable = 1; // Changed in other isolate!
|
|
Expect.equals(1, variable);
|
|
return 42;
|
|
});
|
|
Expect.equals(42, value);
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testAsyncValue() async {
|
|
var value = await Isolate.run<int>(() async {
|
|
variable = 1;
|
|
return 42;
|
|
});
|
|
Expect.equals(42, value);
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testError() async {
|
|
var e = await asyncExpectThrows<ArgumentError>(Isolate.run<int>(() {
|
|
variable = 1;
|
|
Error.throwWithStackTrace(error, stack);
|
|
}));
|
|
Expect.equals(42, e.invalidValue);
|
|
Expect.equals("name", e.name);
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testAsyncError() async {
|
|
var e = await asyncExpectThrows<ArgumentError>(Isolate.run<int>(() async {
|
|
variable = 1;
|
|
Error.throwWithStackTrace(error, stack);
|
|
}));
|
|
Expect.equals(42, e.invalidValue);
|
|
Expect.equals("name", e.name);
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testUncaughtError() async {
|
|
var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
|
|
variable = 1;
|
|
unawaited(Future.error(error, stack)); // Uncaught error
|
|
await Completer().future; // Never completes.
|
|
return -1;
|
|
}));
|
|
|
|
Expect.type<RemoteError>(e);
|
|
Expect.equals(error.toString(), e.toString());
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testIsolateHangs() async {
|
|
var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
|
|
variable = 1;
|
|
await Completer<Never>().future; // Never completes.
|
|
// Isolate should end while hanging here, because its event loop is empty.
|
|
}));
|
|
Expect.type<RemoteError>(e);
|
|
Expect.equals("Computation ended without result", e.toString());
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testIsolateKilled() async {
|
|
var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
|
|
variable = 1;
|
|
Isolate.current.kill(); // Send kill request.
|
|
await Completer<Never>().future; // Never completes.
|
|
// Isolate should get killed while hanging here.
|
|
}));
|
|
Expect.type<RemoteError>(e);
|
|
Expect.equals("Computation ended without result", e.toString());
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testIsolateExits() async {
|
|
var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async {
|
|
variable = 1;
|
|
Isolate.exit(); // Dies here without sending anything back.
|
|
}));
|
|
Expect.type<RemoteError>(e);
|
|
Expect.equals("Computation ended without result", e.toString());
|
|
Expect.equals(0, variable);
|
|
}
|
|
|
|
Future<void> testInvalidMessage() async {
|
|
// Regression test for http://dartbug.com/48516
|
|
var unsendable = RawReceivePort();
|
|
await asyncExpectThrows<Error>(Isolate.run<void>(() => unsendable));
|
|
unsendable.close();
|
|
// Test should not hang.
|
|
}
|