Skip to content

Commit 3684897

Browse files
biggs0125natebiggs
andauthoredDec 20, 2024··
[dwds] Add unbatching retry mechanism for failing batched expression evals (#2552)
[dwds] Add unbatching retry mechanism for failing batched expression evals. --------- Co-authored-by: Nate Biggs <[email protected]>
1 parent edcfbf1 commit 3684897

File tree

4 files changed

+54
-31
lines changed

4 files changed

+54
-31
lines changed
 

‎dwds/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Update to be forward compatible with changes to `package:shelf_web_socket`.
44
- Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537),[#2544](https://github.com/dart-lang/webdev/issues/2544)
5+
- Fix issue where batched expression evals were failing if any subexpression failed. - [#2551](https://github.com/dart-lang/webdev/issues/2551)
56

67
## 24.2.0
78

‎dwds/lib/src/services/batched_expression_evaluator.dart

+26-27
Original file line numberDiff line numberDiff line change
@@ -134,38 +134,37 @@ class BatchedExpressionEvaluator extends ExpressionEvaluator {
134134
first.scope,
135135
);
136136

137+
final listId = list.objectId;
138+
if (listId == null) {
139+
for (final request in requests) {
140+
safeUnawaited(_evaluateBatch([request]));
141+
}
142+
return;
143+
}
144+
137145
for (var i = 0; i < requests.length; i++) {
138146
final request = requests[i];
139147
if (request.completer.isCompleted) continue;
140148
_logger.fine('Getting result out of a batch for ${request.expression}');
141149

142-
final listId = list.objectId;
143-
if (listId == null) {
144-
final error = createError(
145-
EvaluationErrorKind.internal,
146-
'No batch result object ID.',
147-
);
148-
request.completer.complete(error);
149-
} else {
150-
safeUnawaited(
151-
_inspector
152-
.getProperties(
153-
listId,
154-
offset: i,
155-
count: 1,
156-
length: requests.length,
157-
)
158-
.then((v) {
159-
final result = v.first.value!;
160-
_logger.fine(
161-
'Got result out of a batch for ${request.expression}: $result',
162-
);
163-
request.completer.complete(result);
164-
}),
165-
onError: (error, stackTrace) =>
166-
request.completer.completeError(error, stackTrace),
167-
);
168-
}
150+
safeUnawaited(
151+
_inspector
152+
.getProperties(
153+
listId,
154+
offset: i,
155+
count: 1,
156+
length: requests.length,
157+
)
158+
.then((v) {
159+
final result = v.first.value!;
160+
_logger.fine(
161+
'Got result out of a batch for ${request.expression}: $result',
162+
);
163+
request.completer.complete(result);
164+
}),
165+
onError: (error, stackTrace) =>
166+
request.completer.completeError(error, stackTrace),
167+
);
169168
}
170169
}
171170
}

‎dwds/test/expression_evaluator_test.dart

+18-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:dwds/src/debugging/location.dart';
1313
import 'package:dwds/src/debugging/skip_list.dart';
1414
import 'package:dwds/src/services/batched_expression_evaluator.dart';
1515
import 'package:dwds/src/services/expression_evaluator.dart';
16+
import 'package:dwds/src/utilities/shared.dart';
1617

1718
import 'package:test/test.dart';
1819
import 'package:vm_service/vm_service.dart' hide LogRecord;
@@ -36,6 +37,7 @@ void main() async {
3637

3738
late StreamController<DebuggerPausedEvent> pausedController;
3839
late StreamController<Event> debugEventController;
40+
late FakeInspector inspector;
3941
setUp(() async {
4042
final assetReader = FakeAssetReader(sourceMap: '');
4143
final toolConfiguration = TestToolConfiguration.withLoadStrategy(
@@ -64,8 +66,7 @@ void main() async {
6466
skipLists,
6567
root,
6668
);
67-
final inspector =
68-
FakeInspector(webkitDebugger, fakeIsolate: simpleIsolate);
69+
inspector = FakeInspector(webkitDebugger, fakeIsolate: simpleIsolate);
6970
debugger.updateInspector(inspector);
7071

7172
_evaluator = ExpressionEvaluator(
@@ -192,6 +193,21 @@ void main() async {
192193
);
193194
});
194195

196+
test('retries failed batched expression', () async {
197+
safeUnawaited(
198+
evaluator.evaluateExpression('2', 'main.dart', 'true', {}),
199+
);
200+
201+
await evaluator.evaluateExpression('2', 'main.dart', 'false', {});
202+
expect(inspector.functionsCalled.length, 3);
203+
expect(
204+
inspector.functionsCalled[0].contains('return [ true, false ];'),
205+
true,
206+
);
207+
expect(inspector.functionsCalled[1].contains('return true;'), true);
208+
expect(inspector.functionsCalled[2].contains('return false;'), true);
209+
});
210+
195211
test('returns error if closed', () async {
196212
evaluator.close();
197213
final result =

‎dwds/test/fixtures/fakes.dart

+9-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Isolate get simpleIsolate => Isolate(
4848

4949
class FakeInspector implements AppInspector {
5050
final WebkitDebugger _remoteDebugger;
51+
final List<String> functionsCalled = [];
5152
FakeInspector(this._remoteDebugger, {required this.fakeIsolate});
5253

5354
Isolate fakeIsolate;
@@ -61,8 +62,10 @@ class FakeInspector implements AppInspector {
6162
Future<RemoteObject> callFunction(
6263
String function,
6364
Iterable<String> argumentIds,
64-
) async =>
65-
RemoteObject({'type': 'string', 'value': 'true'});
65+
) async {
66+
functionsCalled.add(function);
67+
return RemoteObject({'type': 'string', 'value': 'true'});
68+
}
6669

6770
@override
6871
Future<void> initialize() async => {};
@@ -473,3 +476,7 @@ final fakeWipResponse = WipResponse({
473476
'id': 1,
474477
'result': {'fake': ''},
475478
});
479+
480+
final fakeFailingWipResponse = WipResponse({
481+
'result': 'Error: Bad request',
482+
});

0 commit comments

Comments
 (0)
Please sign in to comment.